summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-09-18 15:53:33 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2012-09-18 15:53:33 +0200
commit6bbb7fbbac94d0f511a7bd0cbd50854ab643bfb2 (patch)
treed9c68d1cca0b3e352f1e438561f3e504e641a08f /Source/JavaScriptCore
parentd0424a769059c84ae20beb3c217812792ea6726b (diff)
downloadqtwebkit-6bbb7fbbac94d0f511a7bd0cbd50854ab643bfb2.tar.gz
Imported WebKit commit c7503cef7ecb236730d1309676ab9fc723fd061d (http://svn.webkit.org/repository/webkit/trunk@128886)
New snapshot with various build fixes
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/ChangeLog975
-rw-r--r--Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig3
-rw-r--r--Source/JavaScriptCore/Configurations/Version.xcconfig2
-rw-r--r--Source/JavaScriptCore/GNUmakefile.list.am1
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln27
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj84
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj173
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh26
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make9
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj173
-rwxr-xr-xSource/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh25
-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.xcodeproj/project.pbxproj4
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h8
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h8
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86.h5
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h6
-rw-r--r--Source/JavaScriptCore/assembler/X86Assembler.h5
-rw-r--r--Source/JavaScriptCore/bytecode/ArrayProfile.cpp5
-rw-r--r--Source/JavaScriptCore/bytecode/ArrayProfile.h10
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h19
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp21
-rw-r--r--Source/JavaScriptCore/dfg/DFGAbstractState.cpp47
-rw-r--r--Source/JavaScriptCore/dfg/DFGArrayMode.cpp32
-rw-r--r--Source/JavaScriptCore/dfg/DFGArrayMode.h23
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp24
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp49
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp59
-rw-r--r--Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp38
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.h4
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp14
-rw-r--r--Source/JavaScriptCore/jit/JIT.h4
-rw-r--r--Source/JavaScriptCore/jit/JITInlineMethods.h29
-rw-r--r--Source/JavaScriptCore/jit/JITOpcodes.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess.cpp23
-rw-r--r--Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp17
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp2
-rw-r--r--Source/JavaScriptCore/jsc.pro4
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp2
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm15
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm33
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter64.asm31
-rw-r--r--Source/JavaScriptCore/offlineasm/armv7.rb2
-rw-r--r--Source/JavaScriptCore/offlineasm/backends.rb3
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp209
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.h164
-rw-r--r--Source/JavaScriptCore/runtime/ArrayPrototype.cpp6
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/FunctionConstructor.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/IndexingType.h59
-rw-r--r--Source/JavaScriptCore/runtime/InitializeThreading.cpp2
-rw-r--r--Source/JavaScriptCore/runtime/JSActivation.h20
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp25
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalData.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.cpp94
-rw-r--r--Source/JavaScriptCore/runtime/JSGlobalObject.h23
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.cpp107
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.h17
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.cpp270
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h111
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.cpp23
-rw-r--r--Source/JavaScriptCore/runtime/JSValue.h3
-rw-r--r--Source/JavaScriptCore/runtime/ObjectPrototype.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp177
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMap.h3
-rw-r--r--Source/JavaScriptCore/runtime/SparseArrayValueMapInlineMethods.h203
-rw-r--r--Source/JavaScriptCore/runtime/Structure.cpp24
-rw-r--r--Source/JavaScriptCore/runtime/Structure.h11
-rw-r--r--Source/JavaScriptCore/runtime/StructureTransitionTable.h12
-rw-r--r--Source/JavaScriptCore/runtime/SymbolTable.h25
82 files changed, 3388 insertions, 824 deletions
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 9e4905f93..76a90cad0 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,978 @@
+2012-09-18 Mark Lam <mark.lam@apple.com>
+
+ Not reviewed. Attempt at greening the WinCairo bot. Touching
+ LowLevelInterpreter.asm to trigger a rebuild of LLIntDesiredOffsets.
+ https://bugs.webkit.org/show_bug.cgi?id=96992.
+
+ * llint/LowLevelInterpreter.asm:
+
+2012-09-18 Peter Gal <galpeter@inf.u-szeged.hu>
+
+ [Qt] REGRESSION(r128790): It broke the ARM build
+ https://bugs.webkit.org/show_bug.cgi?id=96968
+
+ Reviewed by Filip Pizlo.
+
+ Implement the missing or32 method in the MacroAssemblerARM.h.
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::or32):
+ (MacroAssemblerARM):
+
+2012-09-18 Mark Lam <mark.lam@apple.com>
+
+ Fix for WinCairo builds.
+ https://bugs.webkit.org/show_bug.cgi?id=96992.
+
+ Reviewed by Filip Pizlo.
+
+ Adding additional vcproj build targets in LLIntDesiredOffsets.vcproj,
+ LLIntOffsetsExtractor.vcproj, and LLIntAssembly.vcproj to match those
+ in jsc.vcproj.
+
+ * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj:
+ * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj:
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj:
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops: Added.
+
+2012-09-18 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix sloppy English in comment.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC):
+
+2012-09-17 Csaba Osztrogonác <ossy@webkit.org>
+
+ Unreviewed, rolling out r128826 and r128813.
+
+ * API/JSCallbackConstructor.cpp:
+ (JSC):
+ (JSC::JSCallbackConstructor::JSCallbackConstructor):
+ * API/JSCallbackConstructor.h:
+ (JSCallbackConstructor):
+ * API/JSCallbackObject.cpp:
+ (JSC):
+ (JSC::::createStructure):
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObject::create):
+ (JSCallbackObject):
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::prototype):
+ * API/JSObjectRef.cpp:
+ (JSObjectMake):
+ (JSObjectGetPrivate):
+ (JSObjectSetPrivate):
+ (JSObjectGetPrivateProperty):
+ (JSObjectSetPrivateProperty):
+ (JSObjectDeletePrivateProperty):
+ * API/JSValueRef.cpp:
+ (JSValueIsObjectOfClass):
+ * API/JSWeakObjectMapRefPrivate.cpp:
+ * GNUmakefile.list.am:
+ * JSCTypedArrayStubs.h:
+ (JSC):
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject):
+ (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject):
+ * heap/Heap.cpp:
+ (JSC::Heap::isSafeToSweepStructures):
+ (JSC):
+ * heap/Heap.h:
+ (JSC::Heap::allocatorForObjectWithDestructor):
+ (Heap):
+ (JSC::Heap::allocateWithDestructor):
+ (JSC::Heap::allocateStructure):
+ (JSC):
+ * heap/IncrementalSweeper.cpp:
+ (JSC::IncrementalSweeper::IncrementalSweeper):
+ (JSC::IncrementalSweeper::sweepNextBlock):
+ (JSC::IncrementalSweeper::startSweeping):
+ (JSC::IncrementalSweeper::willFinishSweeping):
+ (JSC::IncrementalSweeper::structuresCanBeSwept):
+ (JSC):
+ * heap/IncrementalSweeper.h:
+ (IncrementalSweeper):
+ * heap/MarkedAllocator.cpp:
+ (JSC::MarkedAllocator::tryAllocateHelper):
+ (JSC::MarkedAllocator::allocateBlock):
+ * heap/MarkedAllocator.h:
+ (JSC::MarkedAllocator::cellsNeedDestruction):
+ (JSC::MarkedAllocator::onlyContainsStructures):
+ (MarkedAllocator):
+ (JSC::MarkedAllocator::MarkedAllocator):
+ (JSC::MarkedAllocator::init):
+ * heap/MarkedBlock.cpp:
+ (JSC::MarkedBlock::create):
+ (JSC::MarkedBlock::MarkedBlock):
+ (JSC):
+ (JSC::MarkedBlock::specializedSweep):
+ (JSC::MarkedBlock::sweep):
+ (JSC::MarkedBlock::sweepHelper):
+ * heap/MarkedBlock.h:
+ (JSC):
+ (MarkedBlock):
+ (JSC::MarkedBlock::cellsNeedDestruction):
+ (JSC::MarkedBlock::onlyContainsStructures):
+ * heap/MarkedSpace.cpp:
+ (JSC::MarkedSpace::MarkedSpace):
+ (JSC::MarkedSpace::resetAllocators):
+ (JSC::MarkedSpace::canonicalizeCellLivenessData):
+ (JSC::MarkedSpace::isPagedOut):
+ (JSC::MarkedSpace::freeBlock):
+ * heap/MarkedSpace.h:
+ (MarkedSpace):
+ (Subspace):
+ (JSC::MarkedSpace::allocatorFor):
+ (JSC::MarkedSpace::destructorAllocatorFor):
+ (JSC::MarkedSpace::allocateWithDestructor):
+ (JSC::MarkedSpace::allocateStructure):
+ (JSC::MarkedSpace::forEachBlock):
+ * heap/SlotVisitor.cpp:
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateBasicJSObject):
+ (JSC::JIT::emitAllocateJSFinalObject):
+ (JSC::JIT::emitAllocateJSArray):
+ * jsc.cpp:
+ (GlobalObject::create):
+ * runtime/Arguments.cpp:
+ (JSC):
+ * runtime/Arguments.h:
+ (Arguments):
+ (JSC::Arguments::Arguments):
+ * runtime/ErrorPrototype.cpp:
+ (JSC):
+ * runtime/Executable.h:
+ * runtime/InternalFunction.cpp:
+ (JSC):
+ (JSC::InternalFunction::InternalFunction):
+ * runtime/InternalFunction.h:
+ (InternalFunction):
+ * runtime/JSCell.h:
+ (JSC):
+ (JSC::allocateCell):
+ * runtime/JSDestructibleObject.h: Removed.
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::createRareDataIfNeeded):
+ (JSC::JSGlobalObject::create):
+ * runtime/JSGlobalThis.h:
+ (JSGlobalThis):
+ (JSC::JSGlobalThis::JSGlobalThis):
+ * runtime/JSPropertyNameIterator.h:
+ * runtime/JSScope.cpp:
+ (JSC):
+ * runtime/JSString.h:
+ (JSC):
+ * runtime/JSWrapperObject.h:
+ (JSWrapperObject):
+ (JSC::JSWrapperObject::JSWrapperObject):
+ * runtime/MathObject.cpp:
+ (JSC):
+ * runtime/NameInstance.h:
+ (NameInstance):
+ * runtime/RegExp.h:
+ * runtime/RegExpObject.cpp:
+ (JSC):
+ * runtime/SparseArrayValueMap.h:
+ * runtime/Structure.h:
+ (JSC::Structure):
+ (JSC::JSCell::classInfo):
+ (JSC):
+ * runtime/StructureChain.h:
+ * runtime/SymbolTable.h:
+ * testRegExp.cpp:
+ (GlobalObject::create):
+
+2012-09-17 Geoffrey Garen <ggaren@apple.com>
+
+ Refactored the arguments object so it doesn't dictate closure layout
+ https://bugs.webkit.org/show_bug.cgi?id=96955
+
+ Reviewed by Oliver Hunt.
+
+ * bytecode/CodeBlock.h:
+ (JSC::ExecState::argumentAfterCapture): Helper function for accessing an
+ argument that has been moved for capture.
+
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::BytecodeGenerator): Generate metadata for arguments
+ that are captured. We don't move any arguments yet, but we do use this
+ metadata to tell the arguments object if an argument is stored in the
+ activation.
+
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments):
+ (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile): Updated for the arguments object not
+ malloc'ing a separate backing store, and for a rename from deletedArguments
+ to slowArguments.
+
+ * interpreter/CallFrame.h:
+ (ExecState):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * llint/LLIntSlowPaths.cpp:
+ (JSC::LLInt::LLINT_SLOW_PATH_DECL): Updated for small interface changes.
+
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::visitChildren):
+ (JSC::Arguments::copyToArguments):
+ (JSC::Arguments::fillArgList):
+ (JSC::Arguments::getOwnPropertySlotByIndex):
+ (JSC::Arguments::createStrictModeCallerIfNecessary):
+ (JSC::Arguments::createStrictModeCalleeIfNecessary):
+ (JSC::Arguments::getOwnPropertySlot):
+ (JSC::Arguments::getOwnPropertyDescriptor):
+ (JSC::Arguments::getOwnPropertyNames):
+ (JSC::Arguments::putByIndex):
+ (JSC::Arguments::put):
+ (JSC::Arguments::deletePropertyByIndex):
+ (JSC::Arguments::deleteProperty):
+ (JSC::Arguments::defineOwnProperty):
+ (JSC::Arguments::tearOff): Moved all data inline into the object, for speed,
+ and refactored all internal argument accesses to use helper functions, so
+ we can change the implementation without changing lots of code.
+
+ (JSC::Arguments::didTearOffActivation): This function needs to account
+ for arguments that were moved by the activation object. We do this accounting
+ through a side vector that tells us where our arguments will be in the
+ activation.
+
+ (JSC::Arguments::tearOffForInlineCallFrame):
+ * runtime/Arguments.h:
+ (Arguments):
+ (JSC::Arguments::length):
+ (JSC::Arguments::isTornOff):
+ (JSC::Arguments::Arguments):
+ (JSC::Arguments::allocateSlowArguments):
+ (JSC::Arguments::tryDeleteArgument):
+ (JSC::Arguments::trySetArgument):
+ (JSC::Arguments::tryGetArgument):
+ (JSC::Arguments::isDeletedArgument):
+ (JSC::Arguments::isArgument):
+ (JSC::Arguments::argument):
+ (JSC::Arguments::finishCreation):
+
+ * runtime/JSActivation.h:
+ (JSC::JSActivation::create):
+ (JSActivation):
+ (JSC::JSActivation::captureStart):
+ (JSC::JSActivation::storageSize):
+ (JSC::JSActivation::registerOffset):
+ (JSC::JSActivation::isValid): The activation object is no longer responsible
+ for copying extra arguments provided by the caller. The argumnents object
+ does this instead. This means we can allocate and initialize an activation
+ without worrying about the call frame's argument count.
+
+ * runtime/SymbolTable.h:
+ (JSC::SlowArgument::SlowArgument):
+ (SlowArgument):
+ (JSC):
+ (JSC::SharedSymbolTable::parameterCount):
+ (SharedSymbolTable):
+ (JSC::SharedSymbolTable::slowArguments):
+ (JSC::SharedSymbolTable::setSlowArguments): Added data structures to back
+ the algorithms above.
+
+2012-09-17 Filip Pizlo <fpizlo@apple.com>
+
+ 32-bit LLInt get_by_val does vector length checks incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=96893
+ <rdar://problem/12311678>
+
+ Reviewed by Mark Hahnenberg.
+
+ * llint/LowLevelInterpreter32_64.asm:
+
+2012-09-17 Filip Pizlo <fpizlo@apple.com>
+
+ We don't have a bad enough time if an object's prototype chain crosses global objects
+ https://bugs.webkit.org/show_bug.cgi?id=96962
+
+ Reviewed by Geoffrey Garen.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC):
+
+2012-09-17 Filip Pizlo <fpizlo@apple.com>
+
+ Unreviewed, fix a broken assertion in offlineasm.
+
+ * offlineasm/armv7.rb:
+ * offlineasm/backends.rb:
+
+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 Gavin Barraclough.
+
+ 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 the NEEDS_DESTRUCTOR macro to make it easier for classes to indicate that instead of being
+ allocated in a destructor MarkedAllocator that they will handle their destruction themselves through the
+ use of a finalizer.
+ (JSC):
+ (HasImmortalStructure): New template to help us determine at compile-time if a particular class
+ should be allocated in the immortal structure MarkedAllocator. The default value is false. In order
+ to be allocated in the immortal structure allocator, classes must specialize this template. Also added
+ a macro to make it easier for classes to specialize the template.
+ (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):
+
+2012-09-17 Filip Pizlo <fpizlo@apple.com>
+
+ If a prototype has indexed setters and its instances have indexed storage, then all put_by_val's should have a bad time
+ https://bugs.webkit.org/show_bug.cgi?id=96596
+
+ Reviewed by Gavin Barraclough.
+
+ Added comprehensive support for accessors and read-only indexed properties on the
+ prototype chain. This is done without any performance regression on benchmarks that
+ we're aware of, by having the entire VM's strategy with respect to arrays tilted
+ heavily in favor of:
+
+ - The prototype chain of JSArrays never having any accessors or read-only indexed
+ properties. If that changes, you're going to have a bad time.
+
+ - Prototypes of non-JSArray objects either having no indexed accessors or read-only
+ indexed properties, or, having those indexed accessor thingies inserted before
+ any instance object (i.e. object with that prototype as its prototype) is created.
+ If you add indexed accessors or read-only indexed properties to an object that is
+ already used as a prototype, you're going to have a bad time.
+
+ See below for the exact definition of having a bad time.
+
+ Put another way, "fair" uses of indexed accessors and read-only indexed properties
+ are:
+
+ - Put indexed accessors and read-only indexed properties on an object that is never
+ used as a prototype. This will slow down accesses to that object, but will not
+ have any effect on any other object.
+
+ - Put those indexed accessor thingies on an object before it is used as a prototype
+ and then start instantiating objects that claim that object as their prototype.
+ This will slightly slow down indexed stores to the instance objects, and greatly
+ slow down all indexed accesses to the prototype, but will have no other effect.
+
+ In short, "fair" uses only affect the object itself and any instance objects. But
+ if you start using indexed accessors in more eclectic ways, you're going to have
+ a bad time.
+
+ Specifically, if an object that may be used as a prototype has an indexed accessor
+ added, the VM performs a whole-heap scan to find all objects that belong to the
+ same global object as the prototype you modified. If any of those objects has
+ indexed storage, their indexed storage is put into slow-put mode, just as if their
+ prototype chain had indexed accessors. This will happen even for objects that do
+ not currently have indexed accessors in their prototype chain. As well, all JSArray
+ allocations are caused to create arrays with slow-put storage, and all future
+ allocations of indexed storage for non-JSArray objects are also flipped to slow-put
+ mode. Note there are two aspects to having a bad time: (i) the whole-heap scan and
+ (ii) the poisoning of all indexed storage in the entire global object. (i) is
+ necessary for correctness. If we detect that an object that may be used as a
+ prototype has had an indexed accessor or indexed read-only property inserted into
+ it, then we need to ensure that henceforth all instances of that object inspect
+ the prototype chain whenever an indexed hole is stored to. But by default, indexed
+ stores do no such checking because doing so would be unnecessarily slow. So, we must
+ find all instances of the affected object and flip them into a different array
+ storage mode that omits all hole optimizations. Since prototypes never keep a list
+ of instance objects, the only way to find those objects is a whole-heap scan. But
+ (i) alone would be a potential disaster, if a program frequently allocated an
+ object without indexed accessors, then allocated a bunch of objects that used that
+ one as their prototype, and then added indexed accessors to the prototype. So, to
+ prevent massive heap scan storms in such awkward programs, having a bad time also
+ implies (ii): henceforth *all* objects belonging to that global object will use
+ slow put indexed storage, so that we don't ever have to scan the heap again. Note
+ that here we are using the global object as just an approximation of a program
+ module; it may be worth investigating in the future if other approximations can be
+ used instead.
+
+ * bytecode/ArrayProfile.h:
+ (JSC):
+ (JSC::arrayModeFromStructure):
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGArrayMode.cpp:
+ (JSC::DFG::fromObserved):
+ (JSC::DFG::modeAlreadyChecked):
+ (JSC::DFG::modeToString):
+ * dfg/DFGArrayMode.h:
+ (DFG):
+ (JSC::DFG::isSlowPutAccess):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::checkArray):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::emitAllocateJSArray):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_array):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::ArrayPrototype::finishCreation):
+ (JSC::arrayProtoFuncSort):
+ * runtime/IndexingType.h:
+ (JSC):
+ (JSC::hasIndexedProperties):
+ (JSC::hasIndexingHeader):
+ (JSC::hasArrayStorage):
+ (JSC::shouldUseSlowPut):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::pop):
+ (JSC::JSArray::push):
+ (JSC::JSArray::fillArgList):
+ (JSC::JSArray::copyToArguments):
+ * runtime/JSArray.h:
+ (JSC::JSArray::createStructure):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ (JSC::JSGlobalObject::reset):
+ (JSC):
+ (JSC::JSGlobalObject::haveABadTime):
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::addressOfArrayStructure):
+ (JSC::JSGlobalObject::havingABadTimeWatchpoint):
+ (JSC::JSGlobalObject::isHavingABadTime):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::visitButterfly):
+ (JSC::JSObject::getOwnPropertySlotByIndex):
+ (JSC::JSObject::put):
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::enterDictionaryIndexingMode):
+ (JSC::JSObject::notifyPresenceOfIndexedAccessors):
+ (JSC):
+ (JSC::JSObject::createArrayStorage):
+ (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
+ (JSC::JSObject::switchToSlowPutArrayStorage):
+ (JSC::JSObject::setPrototype):
+ (JSC::JSObject::resetInheritorID):
+ (JSC::JSObject::inheritorID):
+ (JSC::JSObject::allowsAccessFrom):
+ (JSC::JSObject::deletePropertyByIndex):
+ (JSC::JSObject::getOwnPropertyNames):
+ (JSC::JSObject::unwrappedGlobalObject):
+ (JSC::JSObject::notifyUsedAsPrototype):
+ (JSC::JSObject::createInheritorID):
+ (JSC::JSObject::defineOwnIndexedProperty):
+ (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
+ (JSC::JSObject::attemptToInterceptPutByIndexOnHole):
+ (JSC::JSObject::putByIndexBeyondVectorLength):
+ (JSC::JSObject::putDirectIndexBeyondVectorLength):
+ (JSC::JSObject::getNewVectorLength):
+ (JSC::JSObject::getOwnPropertyDescriptor):
+ * runtime/JSObject.h:
+ (JSC::JSObject::mayBeUsedAsPrototype):
+ (JSObject):
+ (JSC::JSObject::mayInterceptIndexedAccesses):
+ (JSC::JSObject::getArrayLength):
+ (JSC::JSObject::getVectorLength):
+ (JSC::JSObject::canGetIndexQuickly):
+ (JSC::JSObject::getIndexQuickly):
+ (JSC::JSObject::canSetIndexQuickly):
+ (JSC::JSObject::setIndexQuickly):
+ (JSC::JSObject::initializeIndex):
+ (JSC::JSObject::completeInitialization):
+ (JSC::JSObject::inSparseIndexingMode):
+ (JSC::JSObject::arrayStorage):
+ (JSC::JSObject::arrayStorageOrNull):
+ (JSC::JSObject::ensureArrayStorage):
+ (JSC):
+ (JSC::JSValue::putByIndex):
+ * runtime/JSValue.cpp:
+ (JSC::JSValue::putToPrimitive):
+ (JSC::JSValue::putToPrimitiveByIndex):
+ (JSC):
+ * runtime/JSValue.h:
+ (JSValue):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::ObjectPrototype::finishCreation):
+ * runtime/SparseArrayValueMap.cpp:
+ (JSC::SparseArrayValueMap::putEntry):
+ (JSC::SparseArrayEntry::put):
+ (JSC):
+ * runtime/SparseArrayValueMap.h:
+ (JSC):
+ (SparseArrayEntry):
+ * runtime/Structure.cpp:
+ (JSC::Structure::anyObjectInChainMayInterceptIndexedAccesses):
+ (JSC):
+ (JSC::Structure::suggestedIndexingTransition):
+ * runtime/Structure.h:
+ (Structure):
+ (JSC::Structure::mayInterceptIndexedAccesses):
+ * runtime/StructureTransitionTable.h:
+ (JSC::newIndexingType):
+
+2012-09-17 Filip Pizlo <fpizlo@apple.com>
+
+ Array profiling has convergence issues
+ https://bugs.webkit.org/show_bug.cgi?id=96891
+
+ Reviewed by Gavin Barraclough.
+
+ Now each array profiling site merges in the indexing type it observed into
+ the m_observedArrayModes bitset. The ArrayProfile also uses this to detect
+ cases where the structure must have gone polymorphic (if the bitset is
+ polymorphic then the structure must be). This achieves something like the
+ best of both worlds: on the one hand, we get a probabilistic structure that
+ we can use to optimize the monomorphic structure case, but on the other hand,
+ we get an accurate view of the set of types that were encountered.
+
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::or32):
+ (MacroAssemblerARMv7):
+ * assembler/MacroAssemblerX86.h:
+ (JSC::MacroAssemblerX86::or32):
+ (MacroAssemblerX86):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::or32):
+ (MacroAssemblerX86_64):
+ * assembler/X86Assembler.h:
+ (X86Assembler):
+ (JSC::X86Assembler::orl_rm):
+ * bytecode/ArrayProfile.cpp:
+ (JSC::ArrayProfile::computeUpdatedPrediction):
+ * bytecode/ArrayProfile.h:
+ (JSC::ArrayProfile::addressOfArrayModes):
+ (JSC::ArrayProfile::structureIsPolymorphic):
+ * jit/JIT.h:
+ (JIT):
+ * jit/JITInlineMethods.h:
+ (JSC):
+ (JSC::JIT::emitArrayProfilingSite):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::emit_op_get_by_val):
+ (JSC::JIT::emit_op_put_by_val):
+ (JSC::JIT::privateCompilePatchGetArrayLength):
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter32_64.asm:
+ * llint/LowLevelInterpreter64.asm:
+
+2012-09-17 Mark Lam <mark.lam@apple.com>
+
+ Not reviewed. Added svn:eol-style native to unbreak some build bots.
+ https://bugs.webkit.org/show_bug.cgi?id=96175.
+
+ * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: Added property svn:eol-style.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: Added property svn:eol-style.
+
+2012-09-16 Mark Lam <mark.lam@apple.com>
+
+ Added MSVC project changes to enable building the llint.
+ https://bugs.webkit.org/show_bug.cgi?id=96175.
+
+ Reviewed by Geoff Garen.
+
+ This only adds the ability to build the llint, but currently, only the
+ C++ backend is supported. By default, the Windows port will remain
+ running with the baseline JIT. The llint will not be enabled.
+
+ * JavaScriptCore.vcproj/JavaScriptCore.sln:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/LLIntAssembly: Added.
+ * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make: Added.
+ * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: Added.
+ * JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh: Added.
+ * JavaScriptCore.vcproj/LLIntDesiredOffsets: Added.
+ * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make: Added.
+ * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: Added.
+ * JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops: Added.
+ * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops: Added.
+
+2012-09-16 Filip Pizlo <fpizlo@apple.com>
+
+ JSObject.cpp and JSArray.cpp have inconsistent tests for the invalid array index case
+ https://bugs.webkit.org/show_bug.cgi?id=96878
+
+ Reviewed by Sam Weinig.
+
+ Removed the uses of UNLIKELY() because I don't believe they are buying us anything,
+ since we're already on the slow path. Also found other places where we're testing for
+ the invalid array index case using unusual predicates rather than just using
+ MAX_ARRAY_INDEX. With this change, I believe that all of our tests for invalid
+ array indices (i.e. indices that should be treated as non-indexed properties)
+ uniformly use MAX_ARRAY_INDEX and PropertyName::NotAnIndex.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::push):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putByIndex):
+ (JSC::JSObject::defineOwnIndexedProperty):
+
+2012-09-15 Filip Pizlo <fpizlo@apple.com>
+
+ Following the Butterfly refactoring, the comment for lastArraySize was not updated
+ https://bugs.webkit.org/show_bug.cgi?id=96877
+
+ Reviewed by Sam Weinig.
+
+ * runtime/JSObject.cpp:
+ (JSC):
+
+2012-09-15 Mark Lam <mark.lam@apple.com>
+
+ Fixed JSLock to use the platform abstraction for Mutex instead of
+ depending on pthreads.
+ https://bugs.webkit.org/show_bug.cgi?id=96858.
+
+ Reviewed by Filip Pizlo.
+
+ This fixes a synchronization problem on the Windows port and makes
+ it more reliable when running the layout tests.
+
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSLock.cpp:
+ (JSC):
+ (JSC::GlobalJSLock::GlobalJSLock):
+ (JSC::GlobalJSLock::~GlobalJSLock):
+ (JSC::GlobalJSLock::initialize):
+ * runtime/JSLock.h:
+ (GlobalJSLock):
+ (JSLock):
+
+2012-09-15 Filip Pizlo <fpizlo@apple.com>
+
+ Structure check hoisting fails to consider the possibility of conflicting checks on the source of the first assignment to the hoisted variable
+ https://bugs.webkit.org/show_bug.cgi?id=96872
+
+ Reviewed by Oliver Hunt.
+
+ This does a few related things:
+
+ - It turns off the use of ForceOSRExit for sure-to-fail CheckStructures, because
+ I noticed that this would sometimes happen for a ForwardCheckStructure. The
+ problem is that ForceOSRExit exits backwards, not forwards. Since the code that
+ led to those ForceOSRExit's being inserted was written out of paranoia rather
+ than need, I removed it. Specifically, I removed the m_isValid = false code
+ for CheckStructure/StructureTransitionWatchpoint in AbstractState.
+
+ - If a structure check causes a structure set to go empty, we don't want a
+ PutStructure to revive the set. It should instead be smart enough to realize
+ that an empty set implies that the code can't execute. This was the only "bug"
+ that the use of m_isValid = false was preventing.
+
+ - Finally, the main change: structure check hoisting looks at the source of the
+ SetLocals on structure-check-hoistable variables and ensures that the source
+ is not checked with a conflicting structure. This is O(n^2) but it does not
+ show up at all in performance tests.
+
+ The first two parts of this change were auxiliary bugs that were revealed by
+ the structure check hoister doing bad things.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::initialize):
+ (JSC::DFG::AbstractState::execute):
+ * dfg/DFGStructureCheckHoistingPhase.cpp:
+ (JSC::DFG::StructureCheckHoistingPhase::run):
+
+2012-09-14 Filip Pizlo <fpizlo@apple.com>
+
+ All of the things in SparseArrayValueMap should be out-of-line
+ https://bugs.webkit.org/show_bug.cgi?id=96854
+
+ Reviewed by Andy Estes.
+
+ Those inline methods were buying us nothing.
+
+ * GNUmakefile.list.am:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSArray.cpp:
+ * runtime/JSGlobalData.cpp:
+ * runtime/JSObject.cpp:
+ * runtime/RegExpMatchesArray.cpp:
+ * runtime/SparseArrayValueMap.cpp:
+ (JSC::SparseArrayValueMap::SparseArrayValueMap):
+ (JSC):
+ (JSC::SparseArrayValueMap::~SparseArrayValueMap):
+ (JSC::SparseArrayValueMap::finishCreation):
+ (JSC::SparseArrayValueMap::create):
+ (JSC::SparseArrayValueMap::destroy):
+ (JSC::SparseArrayValueMap::createStructure):
+ (JSC::SparseArrayValueMap::add):
+ (JSC::SparseArrayValueMap::putEntry):
+ (JSC::SparseArrayValueMap::putDirect):
+ (JSC::SparseArrayEntry::get):
+ (JSC::SparseArrayEntry::getNonSparseMode):
+ (JSC::SparseArrayValueMap::visitChildren):
+ * runtime/SparseArrayValueMapInlineMethods.h: Removed.
+
+2012-09-14 Mike West <mkwst@chromium.org>
+
+ JSC should throw a more descriptive exception when blocking 'eval' via CSP.
+ https://bugs.webkit.org/show_bug.cgi?id=94331
+
+ Reviewed by Geoffrey Garen.
+
+ Unless explicitly whitelisted, the 'script-src' Content Security Policy
+ directive blocks 'eval' and 'eval'-like constructs such as
+ 'new Function()'. When 'eval' is encountered in code, an 'EvalError' is
+ thrown, but the associated message is poor: "Eval is disabled" doesn't
+ give developers enough information about why their code isn't behaving
+ as expected.
+
+ This patch adds an 'errorMessage' parameter to the JavaScriptCore method
+ used to disable 'eval'; ContentSecurityPolicy has the opportunity to
+ pass in a more detailed and descriptive error that contains more context
+ for the developer.
+
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ Drop the hard-coded "Eval is disabled" error message in favor of
+ reading the error message off the global object.
+ * runtime/FunctionConstructor.cpp:
+ (JSC::FunctionConstructor::getCallData):
+ Drop the hard-coded "Function constructor is disabled" error message
+ in favor of reading the error message off the global object.
+ * runtime/JSGlobalObject.h:
+ (JSGlobalObject):
+ (JSC::JSGlobalObject::evalEnabled):
+ Making this accessor method const.
+ (JSC::JSGlobalObject::evalDisabledErrorMessage):
+ Accessor for the error message set via 'setEvalDisabled'.
+ (JSC::JSGlobalObject::setEvalEnabled):
+ Adding an 'errorMessage' parameter which is stored on the global
+ object, and used when exceptions are thrown.
+
+2012-09-14 Filip Pizlo <fpizlo@apple.com>
+
+ bbc homepage crashes immediately
+ https://bugs.webkit.org/show_bug.cgi?id=96812
+ <rdar://problem/12081386>
+
+ Reviewed by Oliver Hunt.
+
+ If you use the old storage pointer to write to space you thought was newly allocated,
+ you're going to have a bad time.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::unshiftCount):
+
+2012-09-14 Adam Barth <abarth@webkit.org>
+
+ Remove webkitPostMessage
+ https://bugs.webkit.org/show_bug.cgi?id=96577
+
+ Reviewed by Ojan Vafai.
+
+ Add ENABLE_LEGACY_VENDOR_PREFIXES flag.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2012-09-14 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ [Qt] Make force_static_libs_as_shared work on Mac OS
+
+ We had to move a few LIBS += around that were in the wrong place,
+ and not caught when everything was just linked into the final
+ QtWebKit library.
+
+ Reviewed by Simon Hausmann.
+
+ * jsc.pro: No need for AppKit, we get it from WTF.pri
+
+2012-09-14 Kevin Funk <kevin.funk@kdab.com>
+
+ Fix interpreter build
+ https://bugs.webkit.org/show_bug.cgi?id=96617
+
+ Reviewed by Simon Hausmann.
+
+ Make compile.
+
+ * interpreter/Interpreter.cpp:
+
2012-09-14 Parth Patel <parpatel@rim.com>
[BlackBerry] Switching from Slogger to Slogger2 requires changes in CMakeList of
diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index f9a0eb29c..ec35cf673 100644
--- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -95,6 +95,7 @@ ENABLE_LEGACY_NOTIFICATIONS_macosx = $(ENABLE_LEGACY_NOTIFICATIONS_macosx_$(TARG
ENABLE_LEGACY_NOTIFICATIONS_macosx_1070 = ;
ENABLE_LEGACY_NOTIFICATIONS_macosx_1080 = ENABLE_LEGACY_NOTIFICATIONS;
ENABLE_LEGACY_NOTIFICATIONS_macosx_1090 = ENABLE_LEGACY_NOTIFICATIONS;
+ENABLE_LEGACY_VENDOR_PREFIXES = ENABLE_LEGACY_VENDOR_PREFIXES;
ENABLE_LINK_PREFETCH = ;
ENABLE_LINK_PRERENDER = ;
ENABLE_MATHML = ENABLE_MATHML;
@@ -139,4 +140,4 @@ ENABLE_WIDGET_REGION_macosx = ENABLE_WIDGET_REGION;
ENABLE_WORKERS = ENABLE_WORKERS;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_HIERARCHIES) $(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_TEXT_DECORATION) $(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_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(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_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_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WIDGET_REGION) $(ENABLE_WORKERS) $(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_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_HIERARCHIES) $(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_TEXT_DECORATION) $(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_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(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_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_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WIDGET_REGION) $(ENABLE_WORKERS) $(ENABLE_XSLT);
diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig
index 5cb8681fa..83578f9e9 100644
--- a/Source/JavaScriptCore/Configurations/Version.xcconfig
+++ b/Source/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 537;
-MINOR_VERSION = 10;
+MINOR_VERSION = 11;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am
index b1715248c..e79542f9e 100644
--- a/Source/JavaScriptCore/GNUmakefile.list.am
+++ b/Source/JavaScriptCore/GNUmakefile.list.am
@@ -647,7 +647,6 @@ javascriptcore_sources += \
Source/JavaScriptCore/runtime/SamplingCounter.h \
Source/JavaScriptCore/runtime/SmallStrings.cpp \
Source/JavaScriptCore/runtime/SmallStrings.h \
- Source/JavaScriptCore/runtime/SparseArrayValueMapInlineMethods.h \
Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp \
Source/JavaScriptCore/runtime/SparseArrayValueMap.h \
Source/JavaScriptCore/runtime/StrictEvalActivation.cpp \
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
index 787abc182..6f4236e03 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.sln
@@ -4,6 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 9.00
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}"
@@ -28,6 +31,30 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testRegExp", "testRegExp\te
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
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index d75be0b67..f5cbbb150 100644
--- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -518,10 +518,6 @@
>
</File>
<File
- RelativePath="..\..\runtime\SparseArrayValueMapInlineMethods.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\ArrayStorage.h"
>
</File>
@@ -965,14 +961,14 @@
RelativePath="..\..\runtime\JSString.h"
>
</File>
- <File
- RelativePath="..\..\runtime\JSStringJoiner.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSStringJoiner.h"
- >
- </File>
+ <File
+ RelativePath="..\..\runtime\JSStringJoiner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\JSStringJoiner.h"
+ >
+ </File>
<File
RelativePath="..\..\runtime\JSSymbolTableObject.cpp"
>
@@ -2022,9 +2018,73 @@
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"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make
new file mode 100644
index 000000000..ea4a72902
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make
@@ -0,0 +1,9 @@
+all:
+ touch "%ConfigurationBuildDir%\buildfailed"
+ bash build-LLIntAssembly.sh "%ConfigurationBuildDir%" "$(WEBKITLIBRARIESDIR)"
+ -del "%ConfigurationBuildDir%\buildfailed"
+
+clean:
+ -del "%ConfigurationBuildDir%\buildfailed"
+ -del /s /q "%ConfigurationBuildDir%\obj\LLIntOffsetsExtractor\LLIntOffsetsExtractor.exe"
+ -del /s /q "%ConfigurationBuildDir%\obj\JavaScriptCore\DerivedSources\LLIntAssembly.h"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj
new file mode 100644
index 000000000..ed6aae895
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj
@@ -0,0 +1,173 @@
+<?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/LLIntAssembly/build-LLIntAssembly.sh b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh
new file mode 100755
index 000000000..a809be776
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/bash
+
+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
+SRCROOT=`cygpath -m -s "$SRCROOT"`
+SRCROOT=`cygpath -u "$SRCROOT"`
+export SRCROOT
+
+XDSTROOT="$1"
+export XDSTROOT
+# 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
+XDSTROOT=`cygpath -m -s "$XDSTROOT"`
+XDSTROOT=`cygpath -u "$XDSTROOT"`
+export XDSTROOT
+
+export BUILT_PRODUCTS_DIR="$XDSTROOT/obj"
+
+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
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make
new file mode 100644
index 000000000..996c92377
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make
@@ -0,0 +1,9 @@
+all:
+ touch "%ConfigurationBuildDir%\buildfailed"
+ bash build-LLIntDesiredOffsets.sh "%ConfigurationBuildDir%" "$(WEBKITLIBRARIESDIR)"
+
+ -del "%ConfigurationBuildDir%\buildfailed"
+
+clean:
+ -del "%ConfigurationBuildDir%\buildfailed"
+ -del /s /q "%ConfigurationBuildDir%\obj\JavaScriptCore\DerivedSources\LLIntDesiredOffsets.h"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj
new file mode 100644
index 000000000..0ece351b0
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj
@@ -0,0 +1,173 @@
+<?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/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh
new file mode 100755
index 000000000..57d715ca1
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/bash
+
+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
+SRCROOT=`cygpath -m -s "$SRCROOT"`
+SRCROOT=`cygpath -u "$SRCROOT"`
+export SRCROOT
+
+XDSTROOT="$1"
+export XDSTROOT
+# 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
+XDSTROOT=`cygpath -m -s "$XDSTROOT"`
+XDSTROOT=`cygpath -u "$XDSTROOT"`
+export XDSTROOT
+
+export BUILT_PRODUCTS_DIR="$XDSTROOT/obj/JavaScriptCore/DerivedSources"
+
+##############################################################################
+# Step 1: Generate LLIntDesiredOffsets.h
+mkdir -p "${BUILT_PRODUCTS_DIR}"
+
+/usr/bin/env ruby "${SRCROOT}/offlineasm/generate_offset_extractor.rb" "${SRCROOT}/llint/LowLevelInterpreter.asm" "${BUILT_PRODUCTS_DIR}/LLIntDesiredOffsets.h"
diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj
new file mode 100644
index 000000000..4862b658a
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj
@@ -0,0 +1,476 @@
+<?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
new file mode 100644
index 000000000..6340081d9
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops
@@ -0,0 +1,20 @@
+<?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
new file mode 100644
index 000000000..69c0a2738
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops
@@ -0,0 +1,8 @@
+<?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
new file mode 100644
index 000000000..e508f9160
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops
@@ -0,0 +1,8 @@
+<?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
new file mode 100644
index 000000000..33804ca90
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops
@@ -0,0 +1,8 @@
+<?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
new file mode 100644
index 000000000..3683199fd
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops
@@ -0,0 +1,8 @@
+<?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
new file mode 100644
index 000000000..b2f4e872d
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops
@@ -0,0 +1,8 @@
+<?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
new file mode 100644
index 000000000..4adb12216
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops
@@ -0,0 +1,8 @@
+<?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
new file mode 100644
index 000000000..331f96af2
--- /dev/null
+++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops
@@ -0,0 +1,12 @@
+<?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.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index db75c0761..7c5ebaded 100644
--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -200,7 +200,6 @@
0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39115ED8E3800F167B2 /* Reject.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 0FB7F39F15ED8E4600F167B2 /* SparseArrayValueMapInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB7F39315ED8E3800F167B2 /* SparseArrayValueMapInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBC0AE71496C7C400D4FBDD /* DFGExitProfile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */; };
0FBC0AE81496C7C700D4FBDD /* DFGExitProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FBD7E691447999600481315 /* CodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBD7E671447998F00481315 /* CodeOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -971,7 +970,6 @@
0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyStorage.h; sourceTree = "<group>"; };
0FB7F39115ED8E3800F167B2 /* Reject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reject.h; sourceTree = "<group>"; };
0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SparseArrayValueMap.h; sourceTree = "<group>"; };
- 0FB7F39315ED8E3800F167B2 /* SparseArrayValueMapInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SparseArrayValueMapInlineMethods.h; sourceTree = "<group>"; };
0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DFGExitProfile.cpp; sourceTree = "<group>"; };
0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFGExitProfile.h; sourceTree = "<group>"; };
0FBD7E671447998F00481315 /* CodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeOrigin.h; sourceTree = "<group>"; };
@@ -2057,7 +2055,6 @@
0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */,
0FB7F39115ED8E3800F167B2 /* Reject.h */,
0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */,
- 0FB7F39315ED8E3800F167B2 /* SparseArrayValueMapInlineMethods.h */,
C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */,
BCF605110E203EF800B9A64D /* ArgList.cpp */,
BCF605120E203EF800B9A64D /* ArgList.h */,
@@ -2952,7 +2949,6 @@
0FB7F39C15ED8E4600F167B2 /* PropertyStorage.h in Headers */,
0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */,
0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */,
- 0FB7F39F15ED8E4600F167B2 /* SparseArrayValueMapInlineMethods.h in Headers */,
0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index e3b0be9da..c4d6c92a5 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -212,6 +212,14 @@ public:
m_assembler.orrs(dest, dest, src);
}
+ void or32(RegisterID src, AbsoluteAddress dest)
+ {
+ move(TrustedImmPtr(dest.m_ptr), ARMRegisters::S0);
+ load32(Address(ARMRegisters::S0), ARMRegisters::S1);
+ or32(src, ARMRegisters::S1);
+ store32(ARMRegisters::S1, ARMRegisters::S0);
+ }
+
void or32(TrustedImm32 imm, RegisterID dest)
{
m_assembler.orrs(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index d2da886c2..1dfe888d3 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -313,6 +313,14 @@ public:
{
m_assembler.orr(dest, dest, src);
}
+
+ void or32(RegisterID src, AbsoluteAddress dest)
+ {
+ move(TrustedImmPtr(dest.m_ptr), addressTempRegister);
+ load32(addressTempRegister, dataTempRegister);
+ or32(src, dataTempRegister);
+ store32(dataTempRegister, addressTempRegister);
+ }
void or32(TrustedImm32 imm, RegisterID dest)
{
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
index d1a4ff3c4..d46867ae3 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
@@ -84,6 +84,11 @@ public:
m_assembler.orl_im(imm.m_value, address.m_ptr);
}
+ void or32(RegisterID reg, AbsoluteAddress address)
+ {
+ m_assembler.orl_rm(reg, address.m_ptr);
+ }
+
void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
m_assembler.subl_im(imm.m_value, address.m_ptr);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index ac90516f4..c827e8ae9 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -75,6 +75,12 @@ public:
or32(imm, Address(scratchRegister));
}
+ void or32(RegisterID reg, AbsoluteAddress address)
+ {
+ move(TrustedImmPtr(address.m_ptr), scratchRegister);
+ or32(reg, Address(scratchRegister));
+ }
+
void sub32(TrustedImm32 imm, AbsoluteAddress address)
{
move(TrustedImmPtr(address.m_ptr), scratchRegister);
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index adaee4bc0..acd573049 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -541,6 +541,11 @@ public:
m_formatter.immediate32(imm);
}
}
+
+ void orl_rm(RegisterID src, const void* addr)
+ {
+ m_formatter.oneByteOp(OP_OR_EvGv, src, addr);
+ }
#endif
void subl_rr(RegisterID src, RegisterID dst)
diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
index 6b97f7806..9f4e1ce20 100644
--- a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp
@@ -43,6 +43,11 @@ void ArrayProfile::computeUpdatedPrediction(OperationInProgress operation)
m_lastSeenStructure = 0;
}
+ if (hasTwoOrMoreBitsSet(m_observedArrayModes)) {
+ m_structureIsPolymorphic = true;
+ m_expectedStructure = 0;
+ }
+
if (operation == Collection
&& m_expectedStructure
&& !Heap::isMarked(m_expectedStructure)) {
diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.h b/Source/JavaScriptCore/bytecode/ArrayProfile.h
index 312473f3c..43818d77d 100644
--- a/Source/JavaScriptCore/bytecode/ArrayProfile.h
+++ b/Source/JavaScriptCore/bytecode/ArrayProfile.h
@@ -36,7 +36,7 @@ namespace JSC {
class LLIntOffsetsExtractor;
// This is a bitfield where each bit represents an IndexingType that we have seen.
-// There are 17 indexing types (0 to 16, inclusive), so 32 bits is more than enough.
+// There are 32 indexing types, so an unsigned is enough.
typedef unsigned ArrayModes;
#define asArrayModes(type) \
@@ -44,7 +44,7 @@ typedef unsigned ArrayModes;
inline ArrayModes arrayModeFromStructure(Structure* structure)
{
- return asArrayModes(structure->indexingTypeIncludingHistory());
+ return asArrayModes(structure->indexingType());
}
class ArrayProfile {
@@ -70,6 +70,7 @@ public:
unsigned bytecodeOffset() const { return m_bytecodeOffset; }
Structure** addressOfLastSeenStructure() { return &m_lastSeenStructure; }
+ ArrayModes* addressOfArrayModes() { return &m_observedArrayModes; }
void observeStructure(Structure* structure)
{
@@ -79,7 +80,10 @@ public:
void computeUpdatedPrediction(OperationInProgress operation = NoOperation);
Structure* expectedStructure() const { return m_expectedStructure; }
- bool structureIsPolymorphic() const { return m_structureIsPolymorphic; }
+ bool structureIsPolymorphic() const
+ {
+ return m_structureIsPolymorphic;
+ }
bool hasDefiniteStructure() const
{
return !structureIsPolymorphic() && m_expectedStructure;
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 07d1e0a06..d0c969c6d 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -1544,6 +1544,25 @@ namespace JSC {
}
#endif
+ inline JSValue ExecState::argumentAfterCapture(size_t argument)
+ {
+ if (argument >= argumentCount())
+ return jsUndefined();
+
+ if (!codeBlock())
+ return this[argumentOffset(argument)].jsValue();
+
+ if (argument >= static_cast<size_t>(codeBlock()->symbolTable()->parameterCount()))
+ return this[argumentOffset(argument)].jsValue();
+
+ const SlowArgument* slowArguments = codeBlock()->symbolTable()->slowArguments();
+ if (!slowArguments || slowArguments[argument].status == SlowArgument::Normal)
+ return this[argumentOffset(argument)].jsValue();
+
+ ASSERT(slowArguments[argument].status == SlowArgument::Captured);
+ return this[slowArguments[argument].indexIfCaptured].jsValue();
+ }
+
#if ENABLE(DFG_JIT)
inline void DFGCodeBlocks::mark(void* candidateCodeBlock)
{
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 055f605d2..e7a80fe2c 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -423,18 +423,19 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc
}
}
- bool capturesAnyArgument = codeBlock->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks; // May reify arguments object.
- if (!capturesAnyArgument && functionBody->hasCapturedVariables()) {
+ bool mayReifyArgumentsObject = codeBlock->usesArguments() || codeBlock->usesEval() || m_shouldEmitDebugHooks;
+ bool capturesAnyArgumentByName = false;
+ if (functionBody->hasCapturedVariables()) {
FunctionParameters& parameters = *functionBody->parameters();
for (size_t i = 0; i < parameters.size(); ++i) {
if (!functionBody->captures(parameters[i]))
continue;
- capturesAnyArgument = true;
+ capturesAnyArgumentByName = true;
break;
}
}
- if (capturesAnyArgument) {
+ if (mayReifyArgumentsObject || capturesAnyArgumentByName) {
symbolTable->setCaptureMode(SharedSymbolTable::AllOfTheThings);
symbolTable->setCaptureStart(-CallFrame::offsetFor(symbolTable->parameterCountIncludingThis()));
} else {
@@ -442,6 +443,16 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, JSScope* sc
symbolTable->setCaptureStart(m_codeBlock->m_numVars);
}
+ if (mayReifyArgumentsObject && capturesAnyArgumentByName) {
+ size_t parameterCount = symbolTable->parameterCount();
+ OwnArrayPtr<SlowArgument> slowArguments = adoptArrayPtr(new SlowArgument[parameterCount]);
+ for (size_t i = 0; i < parameterCount; ++i) {
+ slowArguments[i].status = SlowArgument::Captured;
+ slowArguments[i].indexIfCaptured = CallFrame::argumentOffset(i);
+ }
+ symbolTable->setSlowArguments(slowArguments.release());
+ }
+
RegisterID* calleeRegister = resolveCallee(functionBody); // May push to the scope chain and/or add a captured var.
const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
@@ -681,7 +692,7 @@ bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
SymbolTableEntry entry = symbolTable().get(ident.impl());
if (entry.isNull())
return false;
-
+
if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
return true;
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
index b860a7310..153ba311c 100644
--- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
+++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
@@ -147,7 +147,13 @@ void AbstractState::initialize(Graph& graph)
for (size_t i = 0; i < graph.m_mustHandleValues.size(); ++i) {
AbstractValue value;
value.setMostSpecific(graph.m_mustHandleValues[i]);
- block->valuesAtHead.operand(graph.m_mustHandleValues.operandForIndex(i)).merge(value);
+ int operand = graph.m_mustHandleValues.operandForIndex(i);
+ block->valuesAtHead.operand(operand).merge(value);
+#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
+ dataLog(" Initializing Block #%u, operand r%d, to ", blockIndex, operand);
+ block->valuesAtHead.operand(operand).dump(WTF::dataFile());
+ dataLog("\n");
+#endif
}
block->cfaShouldRevisit = true;
}
@@ -1093,14 +1099,21 @@ bool AbstractState::execute(unsigned indexInBlock)
break;
case NewArray:
- case NewArrayBuffer:
- node.setCanExit(false);
+ node.setCanExit(true);
forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure());
m_haveStructures = true;
break;
+ case NewArrayBuffer:
+ // Unless we're having a bad time, this node can change its mind about what structure
+ // it uses.
+ node.setCanExit(false);
+ forNode(nodeIndex).set(SpecArray);
+ break;
+
case NewArrayWithSize:
- speculateInt32Unary(node);
+ node.setCanExit(true);
+ forNode(node.child1()).filter(SpecInt32);
forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure());
m_haveStructures = true;
break;
@@ -1293,20 +1306,6 @@ bool AbstractState::execute(unsigned indexInBlock)
!value.m_currentKnownStructure.isSubsetOf(set)
|| !isCellSpeculation(value.m_type));
value.filter(set);
- // This is likely to be unnecessary, but it's conservative, and that's a good thing.
- // This is trying to avoid situations where the CFA proves that this structure check
- // must fail due to a future structure proof. We have two options at that point. We
- // can either compile all subsequent code as we would otherwise, or we can ensure
- // that the subsequent code is never reachable. The former is correct because the
- // Proof Is Infallible (TM) -- hence even if we don't force the subsequent code to
- // be unreachable, it must be unreachable nonetheless. But imagine what would happen
- // if the proof was borked. In the former case, we'd get really bizarre bugs where
- // we assumed that the structure of this object was known even though it wasn't. In
- // the latter case, we'd have a slight performance pathology because this would be
- // turned into an OSR exit unnecessarily. Which would you rather have?
- if (value.m_currentKnownStructure.isClear()
- || value.m_futurePossibleStructure.isClear())
- m_isValid = false;
m_haveStructures = true;
break;
}
@@ -1325,10 +1324,6 @@ bool AbstractState::execute(unsigned indexInBlock)
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());
- // See comment in CheckStructure for why this is here.
- if (value.m_currentKnownStructure.isClear()
- || value.m_futurePossibleStructure.isClear())
- m_isValid = false;
m_haveStructures = true;
node.setCanExit(true);
break;
@@ -1337,9 +1332,11 @@ bool AbstractState::execute(unsigned indexInBlock)
case PutStructure:
case PhantomPutStructure:
node.setCanExit(false);
- clobberStructures(indexInBlock);
- forNode(node.child1()).set(node.structureTransitionData().newStructure);
- m_haveStructures = true;
+ if (!forNode(node.child1()).m_currentKnownStructure.isClear()) {
+ clobberStructures(indexInBlock);
+ forNode(node.child1()).set(node.structureTransitionData().newStructure);
+ m_haveStructures = true;
+ }
break;
case GetButterfly:
case AllocatePropertyStorage:
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
index eda578205..fe2a05b8b 100644
--- a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp
@@ -42,10 +42,16 @@ Array::Mode fromObserved(ArrayModes modes, bool makeSafe)
return Array::Undecided;
case asArrayModes(NonArrayWithArrayStorage):
return makeSafe ? Array::ArrayStorageOutOfBounds : Array::ArrayStorage;
+ case asArrayModes(NonArrayWithSlowPutArrayStorage):
+ return Array::SlowPutArrayStorage;
case asArrayModes(ArrayWithArrayStorage):
return makeSafe ? Array::ArrayWithArrayStorageOutOfBounds : Array::ArrayWithArrayStorage;
+ case asArrayModes(ArrayWithSlowPutArrayStorage):
+ return Array::ArrayWithSlowPutArrayStorage;
case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage):
return makeSafe ? Array::PossiblyArrayWithArrayStorageOutOfBounds : Array::PossiblyArrayWithArrayStorage;
+ case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage):
+ return Array::PossiblyArrayWithSlowPutArrayStorage;
default:
// We know that this is possibly a kind of array for which, though there is no
// useful data in the array profile, we may be able to extract useful data from
@@ -124,15 +130,29 @@ bool modeAlreadyChecked(AbstractValue& value, Array::Mode arrayMode)
case Array::String:
return isStringSpeculation(value.m_type);
- case NON_ARRAY_ARRAY_STORAGE_MODES:
+ case Array::ArrayStorage:
+ case Array::ArrayStorageOutOfBounds:
+ case Array::PossiblyArrayWithArrayStorage:
+ case Array::PossiblyArrayWithArrayStorageOutOfBounds:
return value.m_currentKnownStructure.hasSingleton()
&& (value.m_currentKnownStructure.singleton()->indexingType() & HasArrayStorage);
-
- case ARRAY_WITH_ARRAY_STORAGE_MODES:
+
+ case Array::SlowPutArrayStorage:
+ case Array::PossiblyArrayWithSlowPutArrayStorage:
+ return value.m_currentKnownStructure.hasSingleton()
+ && (value.m_currentKnownStructure.singleton()->indexingType() & HasSlowPutArrayStorage);
+
+ case Array::ArrayWithArrayStorage:
+ case Array::ArrayWithArrayStorageOutOfBounds:
return value.m_currentKnownStructure.hasSingleton()
&& (value.m_currentKnownStructure.singleton()->indexingType() & HasArrayStorage)
&& (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
+ case Array::ArrayWithSlowPutArrayStorage:
+ return value.m_currentKnownStructure.hasSingleton()
+ && (value.m_currentKnownStructure.singleton()->indexingType() & HasSlowPutArrayStorage)
+ && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray);
+
case Array::Arguments:
return isArgumentsSpeculation(value.m_type);
@@ -184,14 +204,20 @@ const char* modeToString(Array::Mode mode)
return "String";
case Array::ArrayStorage:
return "ArrayStorage";
+ case Array::SlowPutArrayStorage:
+ return "SlowPutArrayStorage";
case Array::ArrayStorageOutOfBounds:
return "ArrayStorageOutOfBounds";
case Array::ArrayWithArrayStorage:
return "ArrayWithArrayStorage";
+ case Array::ArrayWithSlowPutArrayStorage:
+ return "ArrayWithSlowPutArrayStorage";
case Array::ArrayWithArrayStorageOutOfBounds:
return "ArrayWithArrayStorageOutOfBounds";
case Array::PossiblyArrayWithArrayStorage:
return "PossiblyArrayWithArrayStorage";
+ case Array::PossiblyArrayWithSlowPutArrayStorage:
+ return "PossiblyArrayWithSlowPutArrayStorage";
case Array::PossiblyArrayWithArrayStorageOutOfBounds:
return "PossiblyArrayWithArrayStorageOutOfBounds";
case Array::Arguments:
diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.h b/Source/JavaScriptCore/dfg/DFGArrayMode.h
index 2eb009be0..cc8b1b809 100644
--- a/Source/JavaScriptCore/dfg/DFGArrayMode.h
+++ b/Source/JavaScriptCore/dfg/DFGArrayMode.h
@@ -47,10 +47,13 @@ enum Mode {
Generic,
String,
ArrayStorage,
+ SlowPutArrayStorage,
ArrayStorageOutOfBounds,
ArrayWithArrayStorage,
+ ArrayWithSlowPutArrayStorage,
ArrayWithArrayStorageOutOfBounds,
PossiblyArrayWithArrayStorage,
+ PossiblyArrayWithSlowPutArrayStorage,
PossiblyArrayWithArrayStorageOutOfBounds,
Arguments,
Int8Array,
@@ -70,11 +73,14 @@ enum Mode {
// have the word "ArrayStorage" in them.
#define NON_ARRAY_ARRAY_STORAGE_MODES \
Array::ArrayStorage: \
+ case Array::SlowPutArrayStorage: \
case Array::ArrayStorageOutOfBounds: \
case Array::PossiblyArrayWithArrayStorage: \
+ case Array::PossiblyArrayWithSlowPutArrayStorage: \
case Array::PossiblyArrayWithArrayStorageOutOfBounds
#define ARRAY_WITH_ARRAY_STORAGE_MODES \
Array::ArrayWithArrayStorage: \
+ case Array::ArrayWithSlowPutArrayStorage: \
case Array::ArrayWithArrayStorageOutOfBounds
#define ALL_ARRAY_STORAGE_MODES \
NON_ARRAY_ARRAY_STORAGE_MODES: \
@@ -83,8 +89,13 @@ enum Mode {
Array::ArrayStorage: \
case Array::ArrayWithArrayStorage: \
case Array::PossiblyArrayWithArrayStorage
+#define SLOW_PUT_ARRAY_STORAGE_MODES \
+ Array::SlowPutArrayStorage: \
+ case Array::ArrayWithSlowPutArrayStorage: \
+ case Array::PossiblyArrayWithSlowPutArrayStorage
#define OUT_OF_BOUNDS_ARRAY_STORAGE_MODES \
- Array::ArrayStorageOutOfBounds: \
+ SLOW_PUT_ARRAY_STORAGE_MODES: \
+ case Array::ArrayStorageOutOfBounds: \
case Array::ArrayWithArrayStorageOutOfBounds: \
case Array::PossiblyArrayWithArrayStorageOutOfBounds
@@ -128,6 +139,16 @@ inline bool isInBoundsAccess(Array::Mode arrayMode)
}
}
+inline bool isSlowPutAccess(Array::Mode arrayMode)
+{
+ switch (arrayMode) {
+ case SLOW_PUT_ARRAY_STORAGE_MODES:
+ return true;
+ default:
+ return false;
+ }
+}
+
inline bool canCSEStorage(Array::Mode arrayMode)
{
switch (arrayMode) {
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 19a389218..67ae7bf03 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -1178,7 +1178,7 @@ void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsC
{
ASSERT(exec->codeBlock()->usesArguments());
if (activationCell) {
- jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec->globalData(), jsCast<JSActivation*>(activationCell));
+ jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSActivation*>(activationCell));
return;
}
jsCast<Arguments*>(argumentsCell)->tearOff(exec);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index b1f3212f9..07cb11032 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -324,7 +324,8 @@ void SpeculativeJIT::checkArray(Node& node)
m_jit.branchTest8(
MacroAssembler::Zero,
MacroAssembler::Address(temp.gpr(), Structure::indexingTypeOffset()),
- MacroAssembler::TrustedImm32(HasArrayStorage)));
+ MacroAssembler::TrustedImm32(
+ isSlowPutAccess(node.arrayMode()) ? HasSlowPutArrayStorage : HasArrayStorage)));
noResult(m_compileIndex);
return;
@@ -345,7 +346,8 @@ void SpeculativeJIT::checkArray(Node& node)
speculationCheck(
Uncountable, JSValueRegs(), NoNode,
m_jit.branchTest32(
- MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32(HasArrayStorage)));
+ MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32(
+ isSlowPutAccess(node.arrayMode()) ? HasSlowPutArrayStorage : HasArrayStorage)));
noResult(m_compileIndex);
return;
@@ -3055,28 +3057,24 @@ void SpeculativeJIT::compileGetByValOnArguments(Node& node)
ASSERT(modeAlreadyChecked(m_state.forNode(node.child1()), Array::Arguments));
- m_jit.loadPtr(
- MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
- scratchReg);
-
// Two really lame checks.
speculationCheck(
Uncountable, JSValueSource(), NoNode,
m_jit.branchPtr(
MacroAssembler::AboveOrEqual, propertyReg,
- MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, numArguments))));
+ MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments))));
speculationCheck(
Uncountable, JSValueSource(), NoNode,
m_jit.branchTestPtr(
MacroAssembler::NonZero,
MacroAssembler::Address(
- scratchReg, OBJECT_OFFSETOF(ArgumentsData, deletedArguments))));
+ baseReg, OBJECT_OFFSETOF(Arguments, m_slowArguments))));
m_jit.move(propertyReg, resultReg);
m_jit.neg32(resultReg);
m_jit.signExtend32ToPtr(resultReg, resultReg);
m_jit.loadPtr(
- MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, registers)),
+ MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_registers)),
scratchReg);
#if USE(JSVALUE32_64)
@@ -3116,18 +3114,14 @@ void SpeculativeJIT::compileGetArgumentsLength(Node& node)
ASSERT(modeAlreadyChecked(m_state.forNode(node.child1()), Array::Arguments));
- m_jit.loadPtr(
- MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
- resultReg);
-
speculationCheck(
Uncountable, JSValueSource(), NoNode,
m_jit.branchTest8(
MacroAssembler::NonZero,
- MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, overrodeLength))));
+ MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_overrodeLength))));
m_jit.load32(
- MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, numArguments)),
+ MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments)),
resultReg);
integerResult(resultReg, m_compileIndex);
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
index f40db37a6..85e32ddb9 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -2741,25 +2741,37 @@ void SpeculativeJIT::compile(Node& node)
// Check if we're writing to a hole; if so increment m_numValuesInVector.
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));
- m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
-
- // If we're writing to a hole we might be growing the array;
- MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
- m_jit.add32(TrustedImm32(1), propertyReg);
- m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
- m_jit.sub32(TrustedImm32(1), propertyReg);
-
- lengthDoesNotNeedUpdate.link(&m_jit);
+ MacroAssembler::Jump isHoleValue;
+ if (isSlowPutAccess(arrayMode)) {
+ // This is sort of strange. If we wanted to optimize this code path, we would invert
+ // the above branch. But it's simply not worth it since this only happens if we're
+ // already having a bad time.
+ isHoleValue = m_jit.jump();
+ } else {
+ m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+
+ // If we're writing to a hole we might be growing the array;
+ MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+ m_jit.add32(TrustedImm32(1), propertyReg);
+ m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+ m_jit.sub32(TrustedImm32(1), propertyReg);
+
+ lengthDoesNotNeedUpdate.link(&m_jit);
+ }
notHoleValue.link(&m_jit);
// Store the value to the array.
m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
- if (!isInBoundsAccess(node.arrayMode())) {
+ if (!isInBoundsAccess(arrayMode)) {
+ MacroAssembler::JumpList slowCases;
+ slowCases.append(beyondArrayBounds);
+ if (isSlowPutAccess(arrayMode))
+ slowCases.append(isHoleValue);
addSlowPathGenerator(
slowPathCall(
- beyondArrayBounds, this,
+ slowCases, this,
m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg));
}
@@ -3128,13 +3140,17 @@ void SpeculativeJIT::compile(Node& node)
}
case NewArray: {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
+ if (!globalObject->isHavingABadTime())
+ globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
+
if (!node.numChildren()) {
flushRegisters();
GPRResult result(this);
GPRResult2 resultTagIgnored(this);
callOperation(
operationNewEmptyArray, resultTagIgnored.gpr(), result.gpr(),
- m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure());
+ globalObject->arrayStructure());
cellResult(result.gpr(), m_compileIndex);
break;
}
@@ -3167,8 +3183,7 @@ void SpeculativeJIT::compile(Node& node)
GPRResult2 resultTag(this);
callOperation(
- operationNewArray, resultTag.gpr(), resultPayload.gpr(),
- m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(),
+ operationNewArray, resultTag.gpr(), resultPayload.gpr(), globalObject->arrayStructure(),
static_cast<void *>(buffer), node.numChildren());
if (scratchSize) {
@@ -3184,6 +3199,10 @@ void SpeculativeJIT::compile(Node& node)
}
case NewArrayWithSize: {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
+ if (!globalObject->isHavingABadTime())
+ globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
+
SpeculateStrictInt32Operand size(this, node.child1());
GPRReg sizeGPR = size.gpr();
flushRegisters();
@@ -3191,7 +3210,7 @@ void SpeculativeJIT::compile(Node& node)
GPRResult2 resultTagIgnored(this);
callOperation(
operationNewArrayWithSize, resultTagIgnored.gpr(), result.gpr(),
- m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(), sizeGPR);
+ globalObject->arrayStructure(), sizeGPR);
cellResult(result.gpr(), m_compileIndex);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
index aa5fe6773..f050af699 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
@@ -2760,24 +2760,36 @@ void SpeculativeJIT::compile(Node& node)
// Check if we're writing to a hole; if so increment m_numValuesInVector.
MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
- m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
-
- // If we're writing to a hole we might be growing the array;
- MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
- m_jit.add32(TrustedImm32(1), propertyReg);
- m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
- m_jit.sub32(TrustedImm32(1), propertyReg);
-
- lengthDoesNotNeedUpdate.link(&m_jit);
+ MacroAssembler::Jump isHoleValue;
+ if (isSlowPutAccess(arrayMode)) {
+ // This is sort of strange. If we wanted to optimize this code path, we would invert
+ // the above branch. But it's simply not worth it since this only happens if we're
+ // already having a bad time.
+ isHoleValue = m_jit.jump();
+ } else {
+ m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+
+ // If we're writing to a hole we might be growing the array;
+ MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+ m_jit.add32(TrustedImm32(1), propertyReg);
+ m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
+ m_jit.sub32(TrustedImm32(1), propertyReg);
+
+ lengthDoesNotNeedUpdate.link(&m_jit);
+ }
notHoleValue.link(&m_jit);
// Store the value to the array.
m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
if (!isInBoundsAccess(arrayMode)) {
+ MacroAssembler::JumpList slowCases;
+ slowCases.append(beyondArrayBounds);
+ if (isSlowPutAccess(arrayMode))
+ slowCases.append(isHoleValue);
addSlowPathGenerator(
slowPathCall(
- beyondArrayBounds, this,
+ slowCases, this,
m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
NoResult, baseReg, propertyReg, valueReg));
}
@@ -2798,28 +2810,24 @@ void SpeculativeJIT::compile(Node& node)
if (!m_compileOkay)
return;
- m_jit.loadPtr(
- MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
- scratchReg);
-
// Two really lame checks.
speculationCheck(
Uncountable, JSValueSource(), NoNode,
m_jit.branchPtr(
MacroAssembler::AboveOrEqual, propertyReg,
- MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, numArguments))));
+ MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_numArguments))));
speculationCheck(
Uncountable, JSValueSource(), NoNode,
m_jit.branchTestPtr(
MacroAssembler::NonZero,
MacroAssembler::Address(
- scratchReg, OBJECT_OFFSETOF(ArgumentsData, deletedArguments))));
+ baseReg, OBJECT_OFFSETOF(Arguments, m_slowArguments))));
m_jit.move(propertyReg, scratch2Reg);
m_jit.neg32(scratch2Reg);
m_jit.signExtend32ToPtr(scratch2Reg, scratch2Reg);
m_jit.loadPtr(
- MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, registers)),
+ MacroAssembler::Address(baseReg, OBJECT_OFFSETOF(Arguments, m_registers)),
scratchReg);
m_jit.storePtr(
@@ -3120,12 +3128,14 @@ void SpeculativeJIT::compile(Node& node)
}
case NewArray: {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
+ if (!globalObject->isHavingABadTime())
+ globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
+
if (!node.numChildren()) {
flushRegisters();
GPRResult result(this);
- callOperation(
- operationNewEmptyArray, result.gpr(),
- m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure());
+ callOperation(operationNewEmptyArray, result.gpr(), globalObject->arrayStructure());
cellResult(result.gpr(), m_compileIndex);
break;
}
@@ -3155,8 +3165,7 @@ void SpeculativeJIT::compile(Node& node)
GPRResult result(this);
callOperation(
- operationNewArray, result.gpr(),
- m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(),
+ operationNewArray, result.gpr(), globalObject->arrayStructure(),
static_cast<void*>(buffer), node.numChildren());
if (scratchSize) {
@@ -3171,11 +3180,15 @@ void SpeculativeJIT::compile(Node& node)
}
case NewArrayWithSize: {
+ JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin);
+ if (!globalObject->isHavingABadTime())
+ globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint());
+
SpeculateStrictInt32Operand size(this, node.child1());
GPRReg sizeGPR = size.gpr();
flushRegisters();
GPRResult result(this);
- callOperation(operationNewArrayWithSize, result.gpr(), m_jit.graph().globalObjectFor(node.codeOrigin)->arrayStructure(), sizeGPR);
+ callOperation(operationNewArrayWithSize, result.gpr(), globalObject->arrayStructure(), sizeGPR);
cellResult(result.gpr(), m_compileIndex);
break;
}
diff --git a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
index f6fe127a3..0838bb7e5 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
@@ -67,7 +67,8 @@ public:
if (!node.shouldGenerate())
continue;
switch (node.op()) {
- case CheckStructure: {
+ case CheckStructure:
+ case StructureTransitionWatchpoint: {
Node& child = m_graph[node.child1()];
if (child.op() != GetLocal)
break;
@@ -91,7 +92,6 @@ public:
case GetByOffset:
case PutByOffset:
case PutStructure:
- case StructureTransitionWatchpoint:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
case GetButterfly:
@@ -105,6 +105,40 @@ public:
// 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:
+ case StructureTransitionWatchpoint: {
+ if (subNode.child1().index() != source)
+ break;
+
+ noticeStructureCheck(variable, subNode.structureSet());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ m_graph.vote(node, VoteOther);
+ break;
+ }
+
default:
m_graph.vote(node, VoteOther);
break;
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index 94b37bfc3..da1222ac9 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -187,7 +187,7 @@ namespace JSC {
// Read a register for a non-constant
Register& uncheckedR(int);
- // Access to arguments.
+ // Access to arguments as passed. (After capture, arguments may move to a different location.)
size_t argumentCount() const { return argumentCountIncludingThis() - 1; }
size_t argumentCountIncludingThis() const { return this[RegisterFile::ArgumentCount].payload(); }
static int argumentOffset(int argument) { return s_firstArgumentOffset - argument; }
@@ -208,6 +208,8 @@ namespace JSC {
JSValue thisValue() { return this[thisArgumentOffset()].jsValue(); }
void setThisValue(JSValue value) { this[thisArgumentOffset()] = value; }
+ JSValue argumentAfterCapture(size_t argument);
+
static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize; }
// FIXME: Remove these.
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 739d6022f..ef6cbd5a6 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -473,7 +473,7 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->usesArguments()) {
if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
if (activation)
- jsCast<Arguments*>(arguments)->didTearOffActivation(callFrame->globalData(), jsCast<JSActivation*>(activation));
+ jsCast<Arguments*>(arguments)->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
else
jsCast<Arguments*>(arguments)->tearOff(callFrame);
}
@@ -3610,8 +3610,8 @@ skip_id_custom_self:
uint32_t i = subscript.asUInt32();
if (isJSArray(baseValue)) {
JSArray* jsArray = asArray(baseValue);
- if (jsArray->canGetIndex(i))
- result = jsArray->getIndex(i);
+ if (jsArray->canGetIndexQuickly(i))
+ result = jsArray->getIndexQuickly(i);
else
result = jsArray->JSArray::get(callFrame, i);
} else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
@@ -3652,8 +3652,8 @@ skip_id_custom_self:
uint32_t i = subscript.asUInt32();
if (isJSArray(baseValue)) {
JSArray* jsArray = asArray(baseValue);
- if (jsArray->canSetIndex(i))
- jsArray->setIndex(*globalData, i, callFrame->r(value).jsValue());
+ if (jsArray->canSetIndexQuickly(i))
+ jsArray->setIndexQuickly(*globalData, i, callFrame->r(value).jsValue());
else
jsArray->JSArray::putByIndex(jsArray, callFrame, i, callFrame->r(value).jsValue(), codeBlock->isStrictMode());
} else
@@ -4508,7 +4508,7 @@ skip_id_custom_self:
ASSERT(codeBlock->usesArguments());
if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
if (JSValue activationValue = callFrame->r(activation).jsValue())
- asArguments(argumentsValue)->didTearOffActivation(callFrame->globalData(), asActivation(activationValue));
+ asArguments(argumentsValue)->didTearOffActivation(callFrame, asActivation(activationValue));
else
asArguments(argumentsValue)->tearOff(callFrame);
}
@@ -5012,7 +5012,7 @@ skip_id_custom_self:
accessor->setGetter(callFrame->globalData(), asObject(getter));
if (!setter.isUndefined())
accessor->setSetter(callFrame->globalData(), asObject(setter));
- baseObj->putDirectAccessor(callFrame->globalData(), ident, accessor, Accessor);
+ baseObj->putDirectAccessor(callFrame, ident, accessor, Accessor);
vPC += OPCODE_LENGTH(op_put_getter_setter);
NEXT_INSTRUCTION();
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index ce70b40a7..ac7c8765b 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -437,7 +437,7 @@ namespace JSC {
template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr);
void emitAllocateBasicStorage(size_t, ptrdiff_t offsetFromBase, RegisterID result);
template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr);
- void emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr);
+ void emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr, RegisterID scratch);
#if ENABLE(VALUE_PROFILER)
// This assumes that the value to profile is in regT0 and that regT3 is available for
@@ -449,6 +449,8 @@ namespace JSC {
void emitValueProfilingSite(unsigned) { }
void emitValueProfilingSite() { }
#endif
+ void emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile*);
+ void emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex);
enum FinalObjectMode { MayBeFinal, KnownNotFinal };
diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h
index 35ac44b23..302e109ca 100644
--- a/Source/JavaScriptCore/jit/JITInlineMethods.h
+++ b/Source/JavaScriptCore/jit/JITInlineMethods.h
@@ -443,7 +443,7 @@ inline void JIT::emitAllocateBasicStorage(size_t size, ptrdiff_t offsetFromBase,
subPtr(TrustedImm32(size - offsetFromBase), result);
}
-inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr)
+inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr, RegisterID scratch)
{
unsigned initialLength = std::max(length, 4U);
size_t initialStorage = Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(initialLength));
@@ -453,7 +453,8 @@ inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, R
emitAllocateBasicStorage(initialStorage, sizeof(IndexingHeader), storageResult);
// Allocate the cell for the array.
- emitAllocateBasicJSObject<JSArray, false>(TrustedImmPtr(m_codeBlock->globalObject()->arrayStructure()), cellResult, storagePtr);
+ loadPtr(m_codeBlock->globalObject()->addressOfArrayStructure(), scratch);
+ emitAllocateBasicJSObject<JSArray, false>(scratch, cellResult, storagePtr);
// Store all the necessary info in the ArrayStorage.
store32(Imm32(length), Address(storageResult, ArrayStorage::lengthOffset()));
@@ -529,7 +530,31 @@ inline void JIT::emitValueProfilingSite()
{
emitValueProfilingSite(m_bytecodeOffset);
}
+#endif // ENABLE(VALUE_PROFILER)
+
+inline void JIT::emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile* arrayProfile)
+{
+ RegisterID structure = structureAndIndexingType;
+ RegisterID indexingType = structureAndIndexingType;
+
+ if (canBeOptimized()) {
+ storePtr(structure, arrayProfile->addressOfLastSeenStructure());
+ load8(Address(structure, Structure::indexingTypeOffset()), indexingType);
+ move(TrustedImm32(1), scratch);
+ lshift32(indexingType, scratch);
+ or32(scratch, AbsoluteAddress(arrayProfile->addressOfArrayModes()));
+ } else
+ load8(Address(structure, Structure::indexingTypeOffset()), indexingType);
+}
+
+inline void JIT::emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex)
+{
+#if ENABLE(VALUE_PROFILER)
+ emitArrayProfilingSite(structureAndIndexingType, scratch, m_codeBlock->getOrAddArrayProfile(bytecodeIndex));
+#else
+ emitArrayProfilingSite(structureAndIndexingType, scratch, 0);
#endif
+}
#if USE(JSVALUE32_64)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index 486be6bf9..642aabb2a 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -1676,7 +1676,7 @@ void JIT::emit_op_new_array(Instruction* currentInstruction)
int dst = currentInstruction[1].u.operand;
int values = currentInstruction[2].u.operand;
- emitAllocateJSArray(values, length, regT0, regT1, regT2);
+ emitAllocateJSArray(values, length, regT0, regT1, regT2, regT3);
emitStoreCell(dst, regT0);
}
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
index bca68f0b4..bbc289838 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -111,10 +111,8 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
emitJumpSlowCaseIfNotJSCell(regT0, base);
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
-#if ENABLE(VALUE_PROFILER)
- storePtr(regT2, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
-#endif
- addSlowCase(branchTest8(Zero, Address(regT2, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
+ emitArrayProfilingSite(regT2, regT3, currentInstruction[4].u.arrayProfile);
+ addSlowCase(branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage)));
loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2);
addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset())));
@@ -236,10 +234,8 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
zeroExtend32ToPtr(regT1, regT1);
emitJumpSlowCaseIfNotJSCell(regT0, base);
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
-#if ENABLE(VALUE_PROFILER)
- storePtr(regT2, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
-#endif
- addSlowCase(branchTest8(Zero, Address(regT2, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
+ emitArrayProfilingSite(regT2, regT3, currentInstruction[4].u.arrayProfile);
+ addSlowCase(branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage)));
loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2);
addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset())));
@@ -656,13 +652,10 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);
// Check eax is an array
- loadPtr(Address(regT0, JSCell::structureOffset()), regT3);
-#if ENABLE(VALUE_PROFILER)
- storePtr(regT3, m_codeBlock->getOrAddArrayProfile(stubInfo->bytecodeIndex)->addressOfLastSeenStructure());
-#endif
- load8(Address(regT3, Structure::indexingTypeOffset()), regT3);
- Jump failureCases1 = branchTest32(Zero, regT3, TrustedImm32(IsArray));
- Jump failureCases2 = branchTest32(Zero, regT3, TrustedImm32(HasArrayStorage));
+ loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
+ emitArrayProfilingSiteForBytecodeIndex(regT2, regT1, stubInfo->bytecodeIndex);
+ Jump failureCases1 = branchTest32(Zero, regT2, TrustedImm32(IsArray));
+ Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage));
// Checks out okay! - get the length from the storage
loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index 04d7c3815..1692f33c3 100644
--- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -210,10 +210,8 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
emitJumpSlowCaseIfNotJSCell(base, regT1);
loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
-#if ENABLE(VALUE_PROFILER)
- storePtr(regT1, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
-#endif
- addSlowCase(branchTest8(Zero, Address(regT1, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
+ emitArrayProfilingSite(regT1, regT3, currentInstruction[4].u.arrayProfile);
+ addSlowCase(branchTest32(Zero, regT1, TrustedImm32(HasArrayStorage)));
loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset())));
@@ -269,10 +267,8 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
emitJumpSlowCaseIfNotJSCell(base, regT1);
loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
-#if ENABLE(VALUE_PROFILER)
- storePtr(regT1, currentInstruction[4].u.arrayProfile->addressOfLastSeenStructure());
-#endif
- addSlowCase(branchTest8(Zero, Address(regT1, Structure::indexingTypeOffset()), TrustedImm32(HasArrayStorage)));
+ emitArrayProfilingSite(regT1, regT3, currentInstruction[4].u.arrayProfile);
+ addSlowCase(branchTest32(Zero, regT1, TrustedImm32(HasArrayStorage)));
loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3);
addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset())));
@@ -617,10 +613,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
// Check for array
loadPtr(Address(regT0, JSCell::structureOffset()), regT2);
-#if ENABLE(VALUE_PROFILER)
- storePtr(regT2, m_codeBlock->getOrAddArrayProfile(stubInfo->bytecodeIndex)->addressOfLastSeenStructure());
-#endif
- load8(Address(regT2, Structure::indexingTypeOffset()), regT3);
+ emitArrayProfilingSiteForBytecodeIndex(regT2, regT3, stubInfo->bytecodeIndex);
Jump failureCases1 = branchTest32(Zero, regT2, TrustedImm32(IsArray));
Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage));
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index 40d653b5d..e63f06cef 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -2323,7 +2323,7 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
ASSERT(callFrame->codeBlock()->usesArguments());
Arguments* arguments = jsCast<Arguments*>(stackFrame.args[0].jsValue());
if (JSValue activationValue = stackFrame.args[1].jsValue()) {
- arguments->didTearOffActivation(callFrame->globalData(), jsCast<JSActivation*>(activationValue));
+ arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activationValue));
return;
}
arguments->tearOff(callFrame);
diff --git a/Source/JavaScriptCore/jsc.pro b/Source/JavaScriptCore/jsc.pro
index f226bde40..dfd73e825 100644
--- a/Source/JavaScriptCore/jsc.pro
+++ b/Source/JavaScriptCore/jsc.pro
@@ -19,10 +19,6 @@ WEBKIT += javascriptcore wtf
SOURCES = jsc.cpp
-mac {
- LIBS_PRIVATE += -framework AppKit
-}
-
win32-* {
LIBS += -ladvapi32
}
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index b0441e80b..1ddfca37c 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -1475,7 +1475,7 @@ LLINT_SLOW_PATH_DECL(slow_path_tear_off_arguments)
ASSERT(exec->codeBlock()->usesArguments());
Arguments* arguments = jsCast<Arguments*>(exec->uncheckedR(unmodifiedArgumentsRegister(pc[1].u.operand)).jsValue());
if (JSValue activationValue = LLINT_OP_C(2).jsValue())
- arguments->didTearOffActivation(globalData, jsCast<JSActivation*>(activationValue));
+ arguments->didTearOffActivation(exec, jsCast<JSActivation*>(activationValue));
else
arguments->tearOff(exec);
LLINT_END();
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 6f5460aa7..e347ccc70 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -187,6 +187,20 @@ macro slowPathForCall(advance, slowPath)
end)
end
+macro arrayProfile(structureAndIndexingType, profile, scratch)
+ const structure = structureAndIndexingType
+ const indexingType = structureAndIndexingType
+ if VALUE_PROFILER
+ storep structure, ArrayProfile::m_lastSeenStructure[profile]
+ loadb Structure::m_indexingType[structure], indexingType
+ move 1, scratch
+ lshifti indexingType, scratch
+ ori scratch, ArrayProfile::m_observedArrayModes[profile]
+ else
+ loadb Structure::m_indexingType[structure], indexingType
+ end
+end
+
macro checkSwitchToJIT(increment, action)
if JIT_ENABLED
loadp CodeBlock[cfr], t0
@@ -896,4 +910,3 @@ _llint_op_put_by_id_transition:
# Indicate the end of LLInt.
_llint_end:
crash()
-
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 0e37a4099..41926d8db 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -1176,12 +1176,9 @@ _llint_op_get_array_length:
loadp 16[PC], t1
loadConstantOrVariablePayload(t0, CellTag, t3, .opGetArrayLengthSlow)
loadp JSCell::m_structure[t3], t2
- if VALUE_PROFILER
- storep t2, ArrayProfile::m_lastSeenStructure[t1]
- end
- loadb Structure::m_indexingType[t2], t1
- btiz t1, IsArray, .opGetArrayLengthSlow
- btiz t1, HasArrayStorage, .opGetArrayLengthSlow
+ arrayProfile(t2, t1, t0)
+ btiz t2, IsArray, .opGetArrayLengthSlow
+ btiz t2, HasArrayStorage, .opGetArrayLengthSlow
loadi 4[PC], t1
loadp 32[PC], t2
loadp JSObject::m_butterfly[t3], t0
@@ -1308,17 +1305,15 @@ _llint_op_put_by_id_transition_normal_out_of_line:
_llint_op_get_by_val:
traceExecution()
loadi 8[PC], t2
- loadi 12[PC], t3
loadConstantOrVariablePayload(t2, CellTag, t0, .opGetByValSlow)
+ loadp JSCell::m_structure[t0], t2
+ loadp 16[PC], t3
+ arrayProfile(t2, t3, t1)
+ btiz t2, HasArrayStorage, .opGetByValSlow
+ loadi 12[PC], t3
loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow)
- loadp JSCell::m_structure[t0], t3
- loadp 16[PC], t2
- if VALUE_PROFILER
- storep t3, ArrayProfile::m_lastSeenStructure[t2]
- end
- btpz Structure::m_indexingType[t3], HasArrayStorage, .opGetByValSlow
loadp JSObject::m_butterfly[t0], t3
- biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opGetByValSlow
+ biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow
loadi 4[PC], t0
loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2
loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1
@@ -1392,14 +1387,12 @@ _llint_op_put_by_val:
traceExecution()
loadi 4[PC], t0
loadConstantOrVariablePayload(t0, CellTag, t1, .opPutByValSlow)
+ loadp JSCell::m_structure[t1], t2
+ loadp 16[PC], t0
+ arrayProfile(t2, t0, t3)
+ btiz t2, HasArrayStorage, .opPutByValSlow
loadi 8[PC], t0
loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow)
- loadp JSCell::m_structure[t1], t3
- loadp 16[PC], t0
- if VALUE_PROFILER
- storep t3, ArrayProfile::m_lastSeenStructure[t0]
- end
- btpz Structure::m_indexingType[t3], HasArrayStorage, .opPutByValSlow
loadp JSObject::m_butterfly[t1], t0
biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
index 7dfcb6728..51a11f53f 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
@@ -1023,12 +1023,9 @@ _llint_op_get_array_length:
loadp 32[PB, PC, 8], t1
loadConstantOrVariableCell(t0, t3, .opGetArrayLengthSlow)
loadp JSCell::m_structure[t3], t2
- if VALUE_PROFILER
- storep t2, ArrayProfile::m_lastSeenStructure[t1]
- end
- loadb Structure::m_indexingType[t2], t1
- btiz t1, IsArray, .opGetArrayLengthSlow
- btiz t1, HasArrayStorage, .opGetArrayLengthSlow
+ arrayProfile(t2, t1, t0)
+ btiz t2, IsArray, .opGetArrayLengthSlow
+ btiz t2, HasArrayStorage, .opGetArrayLengthSlow
loadis 8[PB, PC, 8], t1
loadp 64[PB, PC, 8], t2
loadp JSObject::m_butterfly[t3], t0
@@ -1152,16 +1149,14 @@ _llint_op_put_by_id_transition_normal_out_of_line:
_llint_op_get_by_val:
traceExecution()
loadis 16[PB, PC, 8], t2
- loadis 24[PB, PC, 8], t3
loadConstantOrVariableCell(t2, t0, .opGetByValSlow)
+ loadp JSCell::m_structure[t0], t2
+ loadp 32[PB, PC, 8], t3
+ arrayProfile(t2, t3, t1)
+ loadis 24[PB, PC, 8], t3
+ btiz t2, HasArrayStorage, .opGetByValSlow
loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
sxi2p t1, t1
- loadp JSCell::m_structure[t0], t3
- loadp 32[PB, PC, 8], t2
- if VALUE_PROFILER
- storep t3, ArrayProfile::m_lastSeenStructure[t2]
- end
- btbz Structure::m_indexingType[t3], HasArrayStorage, .opGetByValSlow
loadp JSObject::m_butterfly[t0], t3
biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow
loadis 8[PB, PC, 8], t0
@@ -1235,15 +1230,13 @@ _llint_op_put_by_val:
traceExecution()
loadis 8[PB, PC, 8], t0
loadConstantOrVariableCell(t0, t1, .opPutByValSlow)
+ loadp JSCell::m_structure[t1], t2
+ loadp 32[PB, PC, 8], t0
+ arrayProfile(t2, t0, t3)
+ btiz t2, HasArrayStorage, .opPutByValSlow
loadis 16[PB, PC, 8], t0
loadConstantOrVariableInt32(t0, t2, .opPutByValSlow)
sxi2p t2, t2
- loadp JSCell::m_structure[t1], t3
- loadp 32[PB, PC, 8], t0
- if VALUE_PROFILER
- storep t3, ArrayProfile::m_lastSeenStructure[t0]
- end
- btbz Structure::m_indexingType[t3], HasArrayStorage, .opPutByValSlow
loadp JSObject::m_butterfly[t1], t0
biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow
btpz ArrayStorage::m_vector[t0, t2, 8], .opPutByValEmpty
diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb
index eb9472af3..b05f0e57f 100644
--- a/Source/JavaScriptCore/offlineasm/armv7.rb
+++ b/Source/JavaScriptCore/offlineasm/armv7.rb
@@ -683,7 +683,7 @@ def emitArmV7Compact(opcode2, opcode3, operands)
$asm.puts "#{opcode3} #{armV7FlippedOperands(operands)}"
else
raise unless operands.size == 2
- raise unless operands[1].is_a? RegisterID
+ raise unless operands[1].register?
if operands[0].is_a? Immediate
$asm.puts "#{opcode3} #{operands[1].armV7Operand}, #{operands[1].armV7Operand}, #{operands[0].armV7Operand}"
else
diff --git a/Source/JavaScriptCore/offlineasm/backends.rb b/Source/JavaScriptCore/offlineasm/backends.rb
index 0633f07f8..78e545738 100644
--- a/Source/JavaScriptCore/offlineasm/backends.rb
+++ b/Source/JavaScriptCore/offlineasm/backends.rb
@@ -56,7 +56,8 @@ class Node
$activeBackend = name
send("lower" + name)
rescue => e
- raise "Got error #{e} at #{codeOriginString}"
+ e.message << "At #{codeOriginString}"
+ raise e
end
end
end
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index 47795edb2..e5e503ee1 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -45,10 +45,10 @@ void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
JSObject::visitChildren(thisObject, visitor);
- if (thisObject->d->registerArray)
- visitor.appendValues(thisObject->d->registerArray.get(), thisObject->d->numArguments);
- visitor.append(&thisObject->d->callee);
- visitor.append(&thisObject->d->activation);
+ if (thisObject->m_registerArray)
+ visitor.appendValues(thisObject->m_registerArray.get(), thisObject->m_numArguments);
+ visitor.append(&thisObject->m_callee);
+ visitor.append(&thisObject->m_activation);
}
void Arguments::destroy(JSCell* cell)
@@ -58,7 +58,7 @@ void Arguments::destroy(JSCell* cell)
void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length)
{
- if (UNLIKELY(d->overrodeLength)) {
+ if (UNLIKELY(m_overrodeLength)) {
length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
for (unsigned i = 0; i < length; i++)
callFrame->setArgument(i, get(exec, i));
@@ -66,8 +66,8 @@ void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t
}
ASSERT(length == this->length(exec));
for (size_t i = 0; i < length; ++i) {
- if (!d->deletedArguments || !d->deletedArguments[i])
- callFrame->setArgument(i, argument(i).get());
+ if (JSValue value = tryGetArgument(i))
+ callFrame->setArgument(i, value);
else
callFrame->setArgument(i, get(exec, i));
}
@@ -75,7 +75,7 @@ void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t
void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
{
- if (UNLIKELY(d->overrodeLength)) {
+ if (UNLIKELY(m_overrodeLength)) {
unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned i = 0; i < length; i++)
args.append(get(exec, i));
@@ -83,8 +83,8 @@ void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
}
uint32_t length = this->length(exec);
for (size_t i = 0; i < length; ++i) {
- if (!d->deletedArguments || !d->deletedArguments[i])
- args.append(argument(i).get());
+ if (JSValue value = tryGetArgument(i))
+ args.append(value);
else
args.append(get(exec, i));
}
@@ -93,8 +93,8 @@ void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
bool Arguments::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned i, PropertySlot& slot)
{
Arguments* thisObject = jsCast<Arguments*>(cell);
- if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
- slot.setValue(thisObject->argument(i).get());
+ if (JSValue value = thisObject->tryGetArgument(i)) {
+ slot.setValue(value);
return true;
}
@@ -103,10 +103,10 @@ bool Arguments::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigne
void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
{
- if (d->overrodeCaller)
+ if (m_overrodeCaller)
return;
- d->overrodeCaller = true;
+ m_overrodeCaller = true;
PropertyDescriptor descriptor;
descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
methodTable()->defineOwnProperty(this, exec, exec->propertyNames().caller, descriptor, false);
@@ -114,10 +114,10 @@ void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
{
- if (d->overrodeCallee)
+ if (m_overrodeCallee)
return;
- d->overrodeCallee = true;
+ m_overrodeCallee = true;
PropertyDescriptor descriptor;
descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
methodTable()->defineOwnProperty(this, exec, exec->propertyNames().callee, descriptor, false);
@@ -127,26 +127,26 @@ bool Arguments::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName p
{
Arguments* thisObject = jsCast<Arguments*>(cell);
unsigned i = propertyName.asIndex();
- if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
+ if (JSValue value = thisObject->tryGetArgument(i)) {
ASSERT(i < PropertyName::NotAnIndex);
- slot.setValue(thisObject->argument(i).get());
+ slot.setValue(value);
return true;
}
- if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) {
- slot.setValue(jsNumber(thisObject->d->numArguments));
+ if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) {
+ slot.setValue(jsNumber(thisObject->m_numArguments));
return true;
}
- if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) {
- if (!thisObject->d->isStrictMode) {
- slot.setValue(thisObject->d->callee.get());
+ if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) {
+ if (!thisObject->m_isStrictMode) {
+ slot.setValue(thisObject->m_callee.get());
return true;
}
thisObject->createStrictModeCalleeIfNecessary(exec);
}
- if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
+ if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
thisObject->createStrictModeCallerIfNecessary(exec);
return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
@@ -156,26 +156,26 @@ bool Arguments::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prop
{
Arguments* thisObject = jsCast<Arguments*>(object);
unsigned i = propertyName.asIndex();
- if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
+ if (JSValue value = thisObject->tryGetArgument(i)) {
ASSERT(i < PropertyName::NotAnIndex);
- descriptor.setDescriptor(thisObject->argument(i).get(), None);
+ descriptor.setDescriptor(value, None);
return true;
}
- if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) {
- descriptor.setDescriptor(jsNumber(thisObject->d->numArguments), DontEnum);
+ if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->m_overrodeLength)) {
+ descriptor.setDescriptor(jsNumber(thisObject->m_numArguments), DontEnum);
return true;
}
- if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) {
- if (!thisObject->d->isStrictMode) {
- descriptor.setDescriptor(thisObject->d->callee.get(), DontEnum);
+ if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->m_overrodeCallee)) {
+ if (!thisObject->m_isStrictMode) {
+ descriptor.setDescriptor(thisObject->m_callee.get(), DontEnum);
return true;
}
thisObject->createStrictModeCalleeIfNecessary(exec);
}
- if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
+ if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
thisObject->createStrictModeCallerIfNecessary(exec);
return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
@@ -184,9 +184,10 @@ bool Arguments::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prop
void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
Arguments* thisObject = jsCast<Arguments*>(object);
- for (unsigned i = 0; i < thisObject->d->numArguments; ++i) {
- if (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])
- propertyNames.add(Identifier(exec, String::number(i)));
+ for (unsigned i = 0; i < thisObject->m_numArguments; ++i) {
+ if (!thisObject->isArgument(i))
+ continue;
+ propertyNames.add(Identifier(exec, String::number(i)));
}
if (mode == IncludeDontEnumProperties) {
propertyNames.add(exec->propertyNames().callee);
@@ -198,10 +199,8 @@ 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 (i < static_cast<unsigned>(thisObject->d->numArguments) && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
- thisObject->argument(i).set(exec->globalData(), thisObject, value);
+ if (thisObject->trySetArgument(exec->globalData(), i, value))
return;
- }
PutPropertySlot slot(shouldThrow);
JSObject::put(thisObject, exec, Identifier(exec, String::number(i)), value, slot);
@@ -211,28 +210,25 @@ void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JS
{
Arguments* thisObject = jsCast<Arguments*>(cell);
unsigned i = propertyName.asIndex();
- if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
- ASSERT(i < PropertyName::NotAnIndex);
- thisObject->argument(i).set(exec->globalData(), thisObject, value);
+ if (thisObject->trySetArgument(exec->globalData(), i, value))
return;
- }
- if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
- thisObject->d->overrodeLength = true;
+ if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
+ thisObject->m_overrodeLength = true;
thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
return;
}
- if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
- if (!thisObject->d->isStrictMode) {
- thisObject->d->overrodeCallee = true;
+ if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
+ if (!thisObject->m_isStrictMode) {
+ thisObject->m_overrodeCallee = true;
thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
return;
}
thisObject->createStrictModeCalleeIfNecessary(exec);
}
- if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
+ if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
thisObject->createStrictModeCallerIfNecessary(exec);
JSObject::put(thisObject, exec, propertyName, value, slot);
@@ -241,20 +237,12 @@ void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JS
bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
{
Arguments* thisObject = jsCast<Arguments*>(cell);
- if (i < thisObject->d->numArguments) {
+ if (i < thisObject->m_numArguments) {
if (!Base::deletePropertyByIndex(cell, exec, i))
return false;
-
- if (!thisObject->d->deletedArguments) {
- thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
- memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
- }
- if (!thisObject->d->deletedArguments[i]) {
- thisObject->d->deletedArguments[i] = true;
+ if (thisObject->tryDeleteArgument(i))
return true;
- }
}
-
return JSObject::deletePropertyByIndex(thisObject, exec, i);
}
@@ -265,35 +253,28 @@ bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName prope
Arguments* thisObject = jsCast<Arguments*>(cell);
unsigned i = propertyName.asIndex();
- if (i < thisObject->d->numArguments) {
+ if (i < thisObject->m_numArguments) {
ASSERT(i < PropertyName::NotAnIndex);
if (!Base::deleteProperty(cell, exec, propertyName))
return false;
-
- if (!thisObject->d->deletedArguments) {
- thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
- memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
- }
- if (!thisObject->d->deletedArguments[i]) {
- thisObject->d->deletedArguments[i] = true;
+ if (thisObject->tryDeleteArgument(i))
return true;
- }
}
- if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
- thisObject->d->overrodeLength = true;
+ if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
+ thisObject->m_overrodeLength = true;
return true;
}
- if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
- if (!thisObject->d->isStrictMode) {
- thisObject->d->overrodeCallee = true;
+ if (propertyName == exec->propertyNames().callee && !thisObject->m_overrodeCallee) {
+ if (!thisObject->m_isStrictMode) {
+ thisObject->m_overrodeCallee = true;
return true;
}
thisObject->createStrictModeCalleeIfNecessary(exec);
}
- if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
+ if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
thisObject->createStrictModeCallerIfNecessary(exec);
return JSObject::deleteProperty(thisObject, exec, propertyName);
@@ -303,47 +284,46 @@ bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNam
{
Arguments* thisObject = jsCast<Arguments*>(object);
unsigned i = propertyName.asIndex();
- if (i < thisObject->d->numArguments) {
+ if (i < thisObject->m_numArguments) {
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->d->deletedArguments || !thisObject->d->deletedArguments[i]) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
- object->putDirectMayBeIndex(exec, propertyName, thisObject->argument(i).get());
+ if (!thisObject->isDeletedArgument(i) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot)) {
+ JSValue value = thisObject->tryGetArgument(i);
+ ASSERT(value);
+ object->putDirectMayBeIndex(exec, propertyName, value);
+ }
if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
return false;
- if (!thisObject->d->deletedArguments) {
- thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
- memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
- }
// From ES 5.1, 10.6 Arguments Object
// 5. If the value of isMapped is not undefined, then
- if (!thisObject->d->deletedArguments[i]) {
+ if (thisObject->isArgument(i)) {
// a. If IsAccessorDescriptor(Desc) is true, then
if (descriptor.isAccessorDescriptor()) {
// i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
- thisObject->d->deletedArguments[i] = true;
+ thisObject->tryDeleteArgument(i);
} else { // b. Else
// i. If Desc.[[Value]] is present, then
// 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
if (descriptor.value())
- thisObject->argument(i).set(exec->globalData(), thisObject, descriptor.value());
+ thisObject->trySetArgument(exec->globalData(), i, descriptor.value());
// ii. If Desc.[[Writable]] is present and its value is false, then
// 1. Call the [[Delete]] internal method of map passing P and false as arguments.
if (descriptor.writablePresent() && !descriptor.writable())
- thisObject->d->deletedArguments[i] = true;
+ thisObject->tryDeleteArgument(i);
}
}
return true;
}
- if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
- thisObject->putDirect(exec->globalData(), propertyName, jsNumber(thisObject->d->numArguments), DontEnum);
- thisObject->d->overrodeLength = true;
- } else if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
- thisObject->putDirect(exec->globalData(), propertyName, thisObject->d->callee.get(), DontEnum);
- thisObject->d->overrodeCallee = true;
- } else if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
+ if (propertyName == exec->propertyNames().length && !thisObject->m_overrodeLength) {
+ thisObject->putDirect(exec->globalData(), 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->m_overrodeCallee = true;
+ } else if (propertyName == exec->propertyNames().caller && thisObject->m_isStrictMode)
thisObject->createStrictModeCallerIfNecessary(exec);
return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
@@ -354,18 +334,18 @@ void Arguments::tearOff(CallFrame* callFrame)
if (isTornOff())
return;
- if (!d->numArguments)
+ if (!m_numArguments)
return;
// Must be called for the same call frame from which it was created.
- ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == d->registers);
+ ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
- d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
- d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);
+ m_registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[m_numArguments]);
+ m_registers = m_registerArray.get() + CallFrame::offsetFor(m_numArguments + 1);
if (!callFrame->isInlineCallFrame()) {
- for (size_t i = 0; i < d->numArguments; ++i)
- argument(i).set(callFrame->globalData(), this, callFrame->argument(i));
+ for (size_t i = 0; i < m_numArguments; ++i)
+ trySetArgument(callFrame->globalData(), i, callFrame->argumentAfterCapture(i));
return;
}
@@ -373,16 +353,41 @@ void Arguments::tearOff(CallFrame* callFrame)
callFrame->globalData(), callFrame->registers(), callFrame->inlineCallFrame());
}
+void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation)
+{
+ ASSERT(activation);
+ if (isTornOff())
+ return;
+
+ if (!m_numArguments)
+ return;
+
+ tearOff(exec);
+
+ SharedSymbolTable* symbolTable = activation->symbolTable();
+ const SlowArgument* slowArguments = symbolTable->slowArguments();
+ if (!slowArguments)
+ return;
+
+ ASSERT(symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings);
+ m_activation.set(exec->globalData(), this, activation);
+
+ allocateSlowArguments();
+ size_t count = min<unsigned>(m_numArguments, symbolTable->parameterCount());
+ for (size_t i = 0; i < count; ++i)
+ m_slowArguments[i] = slowArguments[i];
+}
+
void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
{
if (isTornOff())
return;
- if (!d->numArguments)
+ if (!m_numArguments)
return;
- d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
- d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);
+ m_registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[m_numArguments]);
+ m_registers = m_registerArray.get() + CallFrame::offsetFor(m_numArguments + 1);
tearOffForInlineCallFrame(
callFrame->globalData(), callFrame->registers() + inlineCallFrame->stackOffset,
@@ -391,7 +396,7 @@ void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* registers, InlineCallFrame* inlineCallFrame)
{
- for (size_t i = 0; i < d->numArguments; ++i) {
+ for (size_t i = 0; i < m_numArguments; ++i) {
ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
// In the future we'll support displaced recoveries (indicating that the
// argument was flushed to a different location), but for now we don't do
@@ -427,7 +432,7 @@ void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* re
ASSERT_NOT_REACHED();
break;
}
- argument(i).set(globalData, this, value);
+ trySetArgument(globalData, i, value);
}
}
diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h
index c3d25f962..ad0e651ea 100644
--- a/Source/JavaScriptCore/runtime/Arguments.h
+++ b/Source/JavaScriptCore/runtime/Arguments.h
@@ -33,31 +33,9 @@
namespace JSC {
- struct ArgumentsData {
- WTF_MAKE_NONCOPYABLE(ArgumentsData); WTF_MAKE_FAST_ALLOCATED;
- public:
- ArgumentsData() { }
- WriteBarrier<JSActivation> activation;
-
- unsigned numArguments;
-
- // We make these full byte booleans to make them easy to test from the JIT,
- // and because even if they were single-bit booleans we still wouldn't save
- // any space.
- bool overrodeLength;
- bool overrodeCallee;
- bool overrodeCaller;
- bool isStrictMode;
-
- WriteBarrierBase<Unknown>* registers;
- OwnArrayPtr<WriteBarrier<Unknown> > registerArray;
-
- OwnArrayPtr<bool> deletedArguments;
-
- WriteBarrier<JSFunction> callee;
- };
-
class Arguments : public JSNonFinalObject {
+ friend class JIT;
+ friend class DFG::SpeculativeJIT;
public:
typedef JSNonFinalObject Base;
@@ -94,30 +72,22 @@ namespace JSC {
uint32_t length(ExecState* exec) const
{
- if (UNLIKELY(d->overrodeLength))
+ if (UNLIKELY(m_overrodeLength))
return get(exec, exec->propertyNames().length).toUInt32(exec);
- return d->numArguments;
+ return m_numArguments;
}
void copyToArguments(ExecState*, CallFrame*, uint32_t length);
void tearOff(CallFrame*);
void tearOff(CallFrame*, InlineCallFrame*);
- bool isTornOff() const { return d->registerArray; }
- void didTearOffActivation(JSGlobalData& globalData, JSActivation* activation)
- {
- if (isTornOff())
- return;
- d->activation.set(globalData, this, activation);
- d->registers = &activation->registerAt(0);
- }
+ bool isTornOff() const { return m_registerArray; }
+ void didTearOffActivation(ExecState*, JSActivation*);
static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
}
- static ptrdiff_t offsetOfData() { return OBJECT_OFFSETOF(Arguments, d); }
-
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
@@ -138,11 +108,34 @@ namespace JSC {
void createStrictModeCallerIfNecessary(ExecState*);
void createStrictModeCalleeIfNecessary(ExecState*);
+ bool isArgument(size_t);
+ bool trySetArgument(JSGlobalData&, size_t argument, JSValue);
+ JSValue tryGetArgument(size_t argument);
+ bool isDeletedArgument(size_t);
+ bool tryDeleteArgument(size_t);
WriteBarrierBase<Unknown>& argument(size_t);
+ void allocateSlowArguments();
void init(CallFrame*);
- OwnPtr<ArgumentsData> d;
+ WriteBarrier<JSActivation> m_activation;
+
+ unsigned m_numArguments;
+
+ // We make these full byte booleans to make them easy to test from the JIT,
+ // and because even if they were single-bit booleans we still wouldn't save
+ // any space.
+ bool m_overrodeLength;
+ bool m_overrodeCallee;
+ bool m_overrodeCaller;
+ bool m_isStrictMode;
+
+ WriteBarrierBase<Unknown>* m_registers;
+ OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray;
+
+ OwnArrayPtr<SlowArgument> m_slowArguments;
+
+ WriteBarrier<JSFunction> m_callee;
};
Arguments* asArguments(JSValue);
@@ -155,19 +148,76 @@ namespace JSC {
inline Arguments::Arguments(CallFrame* callFrame)
: JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
- , d(adoptPtr(new ArgumentsData))
{
}
inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
: JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure())
- , d(adoptPtr(new ArgumentsData))
{
}
- inline WriteBarrierBase<Unknown>& Arguments::argument(size_t i)
+ inline void Arguments::allocateSlowArguments()
+ {
+ if (m_slowArguments)
+ return;
+ m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]);
+ }
+
+ inline bool Arguments::tryDeleteArgument(size_t argument)
{
- return d->registers[CallFrame::argumentOffset(i)];
+ if (!isArgument(argument))
+ return false;
+ allocateSlowArguments();
+ m_slowArguments[argument].status = SlowArgument::Deleted;
+ return true;
+ }
+
+ inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value)
+ {
+ if (!isArgument(argument))
+ return false;
+ this->argument(argument).set(globalData, this, value);
+ return true;
+ }
+
+ inline JSValue Arguments::tryGetArgument(size_t argument)
+ {
+ if (!isArgument(argument))
+ return JSValue();
+ return this->argument(argument).get();
+ }
+
+ inline bool Arguments::isDeletedArgument(size_t argument)
+ {
+ if (argument >= m_numArguments)
+ return false;
+ if (!m_slowArguments)
+ return false;
+ if (m_slowArguments[argument].status != SlowArgument::Deleted)
+ return false;
+ return true;
+ }
+
+ inline bool Arguments::isArgument(size_t argument)
+ {
+ if (argument >= m_numArguments)
+ return false;
+ if (m_slowArguments && m_slowArguments[argument].status == SlowArgument::Deleted)
+ return false;
+ return true;
+ }
+
+ inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument)
+ {
+ ASSERT(isArgument(argument));
+ if (!m_slowArguments || m_slowArguments[argument].status == SlowArgument::Normal)
+ return m_registers[CallFrame::argumentOffset(argument)];
+
+ ASSERT(m_slowArguments[argument].status == SlowArgument::Captured);
+ if (!m_activation)
+ return m_registers[m_slowArguments[argument].indexIfCaptured];
+
+ return m_activation->registerAt(m_slowArguments[argument].indexIfCaptured);
}
inline void Arguments::finishCreation(CallFrame* callFrame)
@@ -176,17 +226,17 @@ namespace JSC {
ASSERT(inherits(&s_info));
JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
- d->numArguments = callFrame->argumentCount();
- d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
- d->callee.set(callFrame->globalData(), this, callee);
- d->overrodeLength = false;
- d->overrodeCallee = false;
- d->overrodeCaller = false;
- d->isStrictMode = callFrame->codeBlock()->isStrictMode();
+ m_numArguments = callFrame->argumentCount();
+ m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());
+ m_callee.set(callFrame->globalData(), this, callee);
+ m_overrodeLength = false;
+ m_overrodeCallee = false;
+ m_overrodeCaller = false;
+ m_isStrictMode = callFrame->codeBlock()->isStrictMode();
// The bytecode generator omits op_tear_off_activation in cases of no
// declared parameters, so we need to tear off immediately.
- if (d->isStrictMode || !callee->jsExecutable()->parameterCount())
+ if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
tearOff(callFrame);
}
@@ -196,17 +246,17 @@ namespace JSC {
ASSERT(inherits(&s_info));
JSFunction* callee = inlineCallFrame->callee.get();
- d->numArguments = inlineCallFrame->arguments.size() - 1;
- d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
- d->callee.set(callFrame->globalData(), this, callee);
- d->overrodeLength = false;
- d->overrodeCallee = false;
- d->overrodeCaller = false;
- d->isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
+ m_numArguments = inlineCallFrame->arguments.size() - 1;
+ m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;
+ m_callee.set(callFrame->globalData(), this, callee);
+ m_overrodeLength = false;
+ m_overrodeCallee = false;
+ m_overrodeCaller = false;
+ m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();
// The bytecode generator omits op_tear_off_activation in cases of no
// declared parameters, so we need to tear off immediately.
- if (d->isStrictMode || !callee->jsExecutable()->parameterCount())
+ if (m_isStrictMode || !callee->jsExecutable()->parameterCount())
tearOff(callFrame, inlineCallFrame);
}
diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
index 503aecda8..c70e40d77 100644
--- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -132,8 +132,10 @@ ArrayPrototype::ArrayPrototype(JSGlobalObject* globalObject, Structure* structur
void ArrayPrototype::finishCreation(JSGlobalObject* globalObject)
{
- Base::finishCreation(globalObject->globalData());
+ JSGlobalData& globalData = globalObject->globalData();
+ Base::finishCreation(globalData);
ASSERT(inherits(&s_info));
+ notifyUsedAsPrototype(globalData);
}
bool ArrayPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
@@ -638,7 +640,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec)
CallData callData;
CallType callType = getCallData(function, callData);
- if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->inSparseIndexingMode()) {
+ if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->inSparseIndexingMode() && !shouldUseSlowPut(thisObj->structure()->indexingType())) {
if (isNumericCompareFunction(exec, callType, callData))
asArray(thisObj)->sortNumeric(exec, function, callType, callData);
else if (callType != CallTypeNone)
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index b11220bea..2791c65d4 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -202,7 +202,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCo
m_evalCodeBlock = newCodeBlock.release();
} else {
if (!lexicalGlobalObject->evalEnabled())
- return throwError(exec, createEvalError(exec, ASCIILiteral("Eval is disabled")));
+ return throwError(exec, createEvalError(exec, lexicalGlobalObject->evalDisabledErrorMessage()));
RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
if (!evalNode) {
ASSERT(exception);
diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
index 40507dae1..570444e3c 100644
--- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -82,7 +82,7 @@ CallType FunctionConstructor::getCallData(JSCell*, CallData& callData)
JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const String& sourceURL, const TextPosition& position)
{
if (!globalObject->evalEnabled())
- return throwError(exec, createEvalError(exec, ASCIILiteral("Function constructor is disabled")));
+ return throwError(exec, createEvalError(exec, globalObject->evalDisabledErrorMessage()));
return constructFunctionSkippingEvalEnabledCheck(exec, globalObject, args, functionName, sourceURL, position);
}
diff --git a/Source/JavaScriptCore/runtime/IndexingType.h b/Source/JavaScriptCore/runtime/IndexingType.h
index cd8d71dfe..3b97230ea 100644
--- a/Source/JavaScriptCore/runtime/IndexingType.h
+++ b/Source/JavaScriptCore/runtime/IndexingType.h
@@ -33,28 +33,65 @@ typedef uint8_t IndexingType;
// Flags for testing the presence of capabilities.
static const IndexingType IsArray = 1;
static const IndexingType HasArrayStorage = 8;
+static const IndexingType HasSlowPutArrayStorage = 16;
// Additional flags for tracking the history of the type. These are usually
// masked off unless you ask for them directly.
-static const IndexingType HadArrayStorage = 16; // Means that this object did have array storage in the past.
+static const IndexingType HadArrayStorage = 32; // Means that this object did have array storage in the past.
+static const IndexingType MayHaveIndexedAccessors = 64;
// List of acceptable array types.
-static const IndexingType NonArray = 0;
-static const IndexingType NonArrayWithArrayStorage = HasArrayStorage;
-static const IndexingType ArrayClass = IsArray; // I'd want to call this "Array" but this would lead to disastrous namespace pollution.
-static const IndexingType ArrayWithArrayStorage = IsArray | HasArrayStorage;
+static const IndexingType NonArray = 0;
+static const IndexingType NonArrayWithArrayStorage = HasArrayStorage;
+static const IndexingType NonArrayWithSlowPutArrayStorage = HasSlowPutArrayStorage;
+static const IndexingType ArrayClass = IsArray; // I'd want to call this "Array" but this would lead to disastrous namespace pollution.
+static const IndexingType ArrayWithArrayStorage = IsArray | HasArrayStorage;
+static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | HasSlowPutArrayStorage;
-// Mask of all possible types.
-static const IndexingType AllArrayTypes = 15;
+#define ALL_BLANK_INDEXING_TYPES \
+ NonArray: \
+ case ArrayClass
-// Mask of all possible types including the history.
-static const IndexingType AllArrayTypesAndHistory = 31;
+#define ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES \
+ ArrayWithArrayStorage: \
+ case ArrayWithSlowPutArrayStorage
+
+#define ALL_ARRAY_STORAGE_INDEXING_TYPES \
+ NonArrayWithArrayStorage: \
+ case NonArrayWithSlowPutArrayStorage: \
+ case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES
+
+static inline bool hasIndexedProperties(IndexingType indexingType)
+{
+ switch (indexingType) {
+ case ALL_BLANK_INDEXING_TYPES:
+ return false;
+ default:
+ return true;
+ }
+}
+
+static inline bool hasIndexingHeader(IndexingType type)
+{
+ return hasIndexedProperties(type);
+}
-inline bool hasIndexingHeader(IndexingType type)
+static inline bool hasArrayStorage(IndexingType indexingType)
{
- return !!(type & HasArrayStorage);
+ return !!(indexingType & (HasArrayStorage | HasSlowPutArrayStorage));
}
+static inline bool shouldUseSlowPut(IndexingType indexingType)
+{
+ return !!(indexingType & HasSlowPutArrayStorage);
+}
+
+// Mask of all possible types.
+static const IndexingType AllArrayTypes = 31;
+
+// Mask of all possible types including the history.
+static const IndexingType AllArrayTypesAndHistory = 127;
+
} // namespace JSC
#endif // IndexingType_h
diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.cpp b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
index 6e7eddbf1..1a7239f60 100644
--- a/Source/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/Source/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -35,6 +35,7 @@
#include "Identifier.h"
#include "JSDateMath.h"
#include "JSGlobalObject.h"
+#include "JSLock.h"
#include "LLIntData.h"
#include "WriteBarrier.h"
#include <wtf/dtoa.h>
@@ -53,6 +54,7 @@ static void initializeThreadingOnce()
{
WTF::double_conversion::initialize();
WTF::initializeThreading();
+ GlobalJSLock::initialize();
Options::initialize();
#if ENABLE(WRITE_BARRIER_PROFILING)
WriteBarrierCounters::initialize();
diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h
index df59c3d94..8211e7710 100644
--- a/Source/JavaScriptCore/runtime/JSActivation.h
+++ b/Source/JavaScriptCore/runtime/JSActivation.h
@@ -48,7 +48,7 @@ namespace JSC {
static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* functionExecutable)
{
- size_t storageSize = JSActivation::storageSize(callFrame, functionExecutable->symbolTable());
+ size_t storageSize = JSActivation::storageSize(functionExecutable->symbolTable());
JSActivation* activation = new (
NotNull,
allocateCell<JSActivation>(
@@ -98,8 +98,8 @@ namespace JSC {
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
static size_t allocationSize(size_t storageSize);
- static size_t storageSize(CallFrame*, SharedSymbolTable*);
- static int captureStart(CallFrame*, SharedSymbolTable*);
+ static size_t storageSize(SharedSymbolTable*);
+ static int captureStart(SharedSymbolTable*);
int registerOffset();
size_t storageSize();
@@ -142,26 +142,26 @@ namespace JSC {
return false;
}
- inline int JSActivation::captureStart(CallFrame* callFrame, SharedSymbolTable* symbolTable)
+ inline int JSActivation::captureStart(SharedSymbolTable* symbolTable)
{
if (symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings)
- return -CallFrame::offsetFor(std::max<size_t>(callFrame->argumentCountIncludingThis(), symbolTable->parameterCountIncludingThis()));
+ return -CallFrame::offsetFor(symbolTable->parameterCountIncludingThis());
return symbolTable->captureStart();
}
- inline size_t JSActivation::storageSize(CallFrame* callFrame, SharedSymbolTable* symbolTable)
+ inline size_t JSActivation::storageSize(SharedSymbolTable* symbolTable)
{
- return symbolTable->captureEnd() - captureStart(callFrame, symbolTable);
+ return symbolTable->captureEnd() - captureStart(symbolTable);
}
inline int JSActivation::registerOffset()
{
- return -captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
+ return -captureStart(symbolTable());
}
inline size_t JSActivation::storageSize()
{
- return storageSize(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
+ return storageSize(symbolTable());
}
inline void JSActivation::tearOff(JSGlobalData& globalData)
@@ -216,7 +216,7 @@ namespace JSC {
inline bool JSActivation::isValid(const SymbolTableEntry& entry)
{
- if (entry.getIndex() < captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable()))
+ if (entry.getIndex() < captureStart(symbolTable()))
return false;
if (entry.getIndex() >= symbolTable()->captureEnd())
return false;
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 241049dce..ebbbd41aa 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -34,7 +34,6 @@
#include "IndexingHeaderInlineMethods.h"
#include "PropertyNameArray.h"
#include "Reject.h"
-#include "SparseArrayValueMapInlineMethods.h"
#include <wtf/AVLTree.h>
#include <wtf/Assertions.h>
#include <wtf/OwnPtr.h>
@@ -405,7 +404,7 @@ JSValue JSArray::pop(ExecState* exec)
case ArrayClass:
return jsUndefined();
- case ArrayWithArrayStorage: {
+ case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
unsigned length = storage->length();
@@ -465,6 +464,16 @@ void JSArray::push(ExecState* exec, JSValue value)
break;
}
+ case ArrayWithSlowPutArrayStorage: {
+ unsigned oldLength = length();
+ if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true)) {
+ if (!exec->hadException() && oldLength < 0xFFFFFFFFu)
+ setLength(exec, oldLength + 1, true);
+ return;
+ }
+ // Fall through.
+ }
+
case ArrayWithArrayStorage: {
ArrayStorage* storage = m_butterfly->arrayStorage();
@@ -478,8 +487,8 @@ void JSArray::push(ExecState* exec, JSValue value)
return;
}
- // Pushing to an array of length 2^32-1 stores the property, but throws a range error.
- if (UNLIKELY(storage->length() == 0xFFFFFFFFu)) {
+ // Pushing to an array of invalid length (2^31-1) stores the property, but throws a range error.
+ if (storage->length() > MAX_ARRAY_INDEX) {
methodTable()->putByIndex(this, exec, storage->length(), value, true);
// Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d.
if (!exec->hadException())
@@ -549,7 +558,9 @@ bool JSArray::unshiftCount(ExecState* exec, unsigned count)
storage = m_butterfly->arrayStorage();
storage->m_indexBias -= count;
storage->setVectorLength(storage->vectorLength() + count);
- } else if (!unshiftCountSlowCase(exec->globalData(), count)) {
+ } else if (unshiftCountSlowCase(exec->globalData(), count))
+ storage = arrayStorage();
+ else {
throwOutOfMemoryError(exec);
return true;
}
@@ -916,7 +927,7 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
case ArrayClass:
return;
- case ArrayWithArrayStorage: {
+ case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
WriteBarrier<Unknown>* vector = storage->m_vector;
@@ -946,7 +957,7 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t le
case ArrayClass:
return;
- case ArrayWithArrayStorage: {
+ case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
unsigned i = 0;
WriteBarrier<Unknown>* vector = storage->m_vector;
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index d382f64a9..c46e67863 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -78,9 +78,9 @@ namespace JSC {
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToArguments(ExecState*, CallFrame*, uint32_t length);
- static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+ static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, ArrayWithArrayStorage);
+ return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info, indexingType);
}
protected:
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
index e409c8219..26f2b8616 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -55,7 +55,6 @@
#include "ParserArena.h"
#include "RegExpCache.h"
#include "RegExpObject.h"
-#include "SparseArrayValueMapInlineMethods.h"
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
#include <wtf/RetainPtr.h>
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 8ee8e1498..a6993aabc 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -111,6 +111,7 @@ static const int preferredScriptCheckTimeInterval = 1000;
JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable)
: Base(globalData, 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)))
, m_evalEnabled(true)
, m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
@@ -230,7 +231,8 @@ void JSGlobalObject::reset(JSValue prototype)
m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSNonFinalObject>::createStructure(exec->globalData(), this, m_objectPrototype.get()));
m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
- m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get()));
+ m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage));
+ m_arrayStructureForSlowPut.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage));
m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), this, m_arrayPrototype.get()));
m_stringPrototype.set(exec->globalData(), this, StringPrototype::create(exec, this, StringPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())));
@@ -329,6 +331,96 @@ void JSGlobalObject::reset(JSValue prototype)
resetPrototype(exec->globalData(), prototype);
}
+// Private namespace for helpers for JSGlobalObject::haveABadTime()
+namespace {
+
+class ObjectsWithBrokenIndexingFinder : public MarkedBlock::VoidFunctor {
+public:
+ ObjectsWithBrokenIndexingFinder(MarkedArgumentBuffer&, JSGlobalObject*);
+ void operator()(JSCell*);
+
+private:
+ MarkedArgumentBuffer& m_foundObjects;
+ JSGlobalObject* m_globalObject;
+};
+
+ObjectsWithBrokenIndexingFinder::ObjectsWithBrokenIndexingFinder(
+ MarkedArgumentBuffer& foundObjects, JSGlobalObject* globalObject)
+ : m_foundObjects(foundObjects)
+ , m_globalObject(globalObject)
+{
+}
+
+inline bool hasBrokenIndexing(JSObject* object)
+{
+ // This will change if we have more indexing types.
+ return !!(object->structure()->indexingType() & HasArrayStorage);
+}
+
+void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell)
+{
+ if (!cell->isObject())
+ return;
+
+ JSObject* object = asObject(cell);
+
+ // Run this filter first, since it's cheap, and ought to filter out a lot of objects.
+ if (!hasBrokenIndexing(object))
+ return;
+
+ // We only want to have a bad time in the affected global object, not in the entire
+ // VM. But we have to be careful, since there may be objects that claim to belong to
+ // a different global object that have prototypes from our global object.
+ bool foundGlobalObject = false;
+ for (JSObject* current = object; ;) {
+ if (current->unwrappedGlobalObject() == m_globalObject) {
+ foundGlobalObject = true;
+ break;
+ }
+
+ JSValue prototypeValue = current->prototype();
+ if (prototypeValue.isNull())
+ break;
+ current = asObject(prototypeValue);
+ }
+ if (!foundGlobalObject)
+ return;
+
+ m_foundObjects.append(object);
+}
+
+} // end private namespace for helpers for JSGlobalObject::haveABadTime()
+
+void JSGlobalObject::haveABadTime(JSGlobalData& globalData)
+{
+ ASSERT(&globalData == &this->globalData());
+
+ if (isHavingABadTime())
+ return;
+
+ // Make sure that all allocations or indexed storage transitions that are inlining
+ // the assumption that it's safe to transition to a non-SlowPut array storage don't
+ // do so anymore.
+ m_havingABadTimeWatchpoint->notifyWrite();
+ ASSERT(isHavingABadTime()); // The watchpoint is what tells us that we're having a bad time.
+
+ // Make sure that all JSArray allocations that load the appropriate structure from
+ // this object now load a structure that uses SlowPut.
+ m_arrayStructure.set(globalData, this, m_arrayStructureForSlowPut.get());
+
+ // 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);
+ while (!foundObjects.isEmpty()) {
+ JSObject* object = asObject(foundObjects.last());
+ foundObjects.removeLast();
+ ASSERT(hasBrokenIndexing(object));
+ object->switchToSlowPutArrayStorage(globalData);
+ }
+}
+
void JSGlobalObject::createThrowTypeError(ExecState* exec)
{
JSFunction* thrower = JSFunction::create(exec, this, 0, String(), globalFuncThrowTypeError);
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 406a65b51..ad56783cc 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -126,7 +126,8 @@ namespace JSC {
WriteBarrier<Structure> m_activationStructure;
WriteBarrier<Structure> m_nameScopeStructure;
WriteBarrier<Structure> m_argumentsStructure;
- WriteBarrier<Structure> m_arrayStructure;
+ WriteBarrier<Structure> m_arrayStructure; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time.
+ WriteBarrier<Structure> m_arrayStructureForSlowPut;
WriteBarrier<Structure> m_booleanObjectStructure;
WriteBarrier<Structure> m_callbackConstructorStructure;
WriteBarrier<Structure> m_callbackFunctionStructure;
@@ -149,12 +150,14 @@ namespace JSC {
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;
@@ -259,6 +262,7 @@ namespace JSC {
Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); }
Structure* argumentsStructure() const { return m_argumentsStructure.get(); }
Structure* arrayStructure() const { return m_arrayStructure.get(); }
+ void* addressOfArrayStructure() { return &m_arrayStructure; }
Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); }
Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); }
Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); }
@@ -279,6 +283,14 @@ namespace JSC {
Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); }
+ WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); }
+
+ bool isHavingABadTime() const
+ {
+ return m_havingABadTimeWatchpoint->hasBeenInvalidated();
+ }
+
+ void haveABadTime(JSGlobalData&);
void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; }
unsigned profileGroup() const
@@ -304,8 +316,13 @@ namespace JSC {
bool isDynamicScope(bool& requiresDynamicChecks) const;
- void setEvalEnabled(bool enabled) { m_evalEnabled = enabled; }
- bool evalEnabled() { return m_evalEnabled; }
+ 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);
diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp
index c57c9cdc5..9f02b69b8 100644
--- a/Source/JavaScriptCore/runtime/JSLock.cpp
+++ b/Source/JavaScriptCore/runtime/JSLock.cpp
@@ -33,21 +33,21 @@
namespace JSC {
-// JSLock is only needed to support an obsolete execution model where JavaScriptCore
-// automatically protected against concurrent access from multiple threads.
-// So it's safe to disable it on non-mac platforms where we don't have native pthreads.
-#if (OS(DARWIN) || USE(PTHREADS))
-
-static pthread_mutex_t sharedInstanceLock = PTHREAD_MUTEX_INITIALIZER;
+Mutex* GlobalJSLock::s_sharedInstanceLock = 0;
GlobalJSLock::GlobalJSLock()
{
- pthread_mutex_lock(&sharedInstanceLock);
+ s_sharedInstanceLock->lock();
}
GlobalJSLock::~GlobalJSLock()
{
- pthread_mutex_unlock(&sharedInstanceLock);
+ s_sharedInstanceLock->unlock();
+}
+
+void GlobalJSLock::initialize()
+{
+ s_sharedInstanceLock = new Mutex();
}
JSLockHolder::JSLockHolder(ExecState* exec)
@@ -216,95 +216,4 @@ JSLock::DropAllLocks::~DropAllLocks()
m_globalData->apiLock().grabAllLocks(m_lockCount);
}
-#else // (OS(DARWIN) || USE(PTHREADS))
-
-GlobalJSLock::GlobalJSLock()
-{
-}
-
-GlobalJSLock::~GlobalJSLock()
-{
-}
-
-JSLockHolder::JSLockHolder(JSGlobalData*)
-{
-}
-
-JSLockHolder::JSLockHolder(JSGlobalData&)
-{
-}
-
-JSLockHolder::JSLockHolder(ExecState*)
-{
-}
-
-JSLockHolder::~JSLockHolder()
-{
-}
-
-JSLock::JSLock()
-{
-}
-
-JSLock::~JSLock()
-{
-}
-
-bool JSLock::currentThreadIsHoldingLock()
-{
- return true;
-}
-
-void JSLock::lock()
-{
-}
-
-void JSLock::unlock()
-{
-}
-
-void JSLock::lock(ExecState*)
-{
-}
-
-void JSLock::unlock(ExecState*)
-{
-}
-
-void JSLock::lock(JSGlobalData&)
-{
-}
-
-void JSLock::unlock(JSGlobalData&)
-{
-}
-
-unsigned JSLock::dropAllLocks()
-{
- return 0;
-}
-
-unsigned JSLock::dropAllLocksUnconditionally()
-{
- return 0;
-}
-
-void JSLock::grabAllLocks(unsigned)
-{
-}
-
-JSLock::DropAllLocks::DropAllLocks(ExecState*)
-{
-}
-
-JSLock::DropAllLocks::DropAllLocks(JSGlobalData*)
-{
-}
-
-JSLock::DropAllLocks::~DropAllLocks()
-{
-}
-
-#endif // (OS(DARWIN) || USE(PTHREADS))
-
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/JSLock.h b/Source/JavaScriptCore/runtime/JSLock.h
index 94108d013..4c42dc0ae 100644
--- a/Source/JavaScriptCore/runtime/JSLock.h
+++ b/Source/JavaScriptCore/runtime/JSLock.h
@@ -58,6 +58,10 @@ namespace JSC {
public:
JS_EXPORT_PRIVATE GlobalJSLock();
JS_EXPORT_PRIVATE ~GlobalJSLock();
+
+ static void initialize();
+ private:
+ static Mutex* s_sharedInstanceLock;
};
class JSLockHolder {
@@ -91,12 +95,6 @@ namespace JSC {
unsigned dropAllLocksUnconditionally();
void grabAllLocks(unsigned lockCount);
- SpinLock m_spinLock;
- Mutex m_lock;
- ThreadIdentifier m_ownerThread;
- intptr_t m_lockCount;
- unsigned m_lockDropDepth;
-
class DropAllLocks {
WTF_MAKE_NONCOPYABLE(DropAllLocks);
public:
@@ -108,6 +106,13 @@ namespace JSC {
intptr_t m_lockCount;
RefPtr<JSGlobalData> m_globalData;
};
+
+ private:
+ SpinLock m_spinLock;
+ Mutex m_lock;
+ ThreadIdentifier m_ownerThread;
+ intptr_t m_lockCount;
+ unsigned m_lockDropDepth;
};
} // namespace
diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp
index 6eac0d1cb..229d1aea6 100644
--- a/Source/JavaScriptCore/runtime/JSObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSObject.cpp
@@ -42,7 +42,6 @@
#include "PropertyNameArray.h"
#include "Reject.h"
#include "SlotVisitorInlineMethods.h"
-#include "SparseArrayValueMapInlineMethods.h"
#include <math.h>
#include <wtf/Assertions.h>
@@ -50,7 +49,8 @@ namespace JSC {
// We keep track of the size of the last array after it was grown. We use this
// as a simple heuristic for as the value to grow the next array from size 0.
-// This value is capped by the constant FIRST_VECTOR_GROW defined above.
+// This value is capped by the constant FIRST_VECTOR_GROW defined in
+// ArrayConventions.h.
static unsigned lastArraySize = 0;
JSCell* getCallableObjectSlow(JSCell* cell)
@@ -133,8 +133,7 @@ ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* but
// Mark and copy the array if appropriate.
switch (structure->indexingType()) {
- case ArrayWithArrayStorage:
- case NonArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
newButterfly->arrayStorage()->copyHeaderFromDuringGC(*butterfly->arrayStorage());
WriteBarrier<Unknown>* currentTarget = newButterfly->arrayStorage()->m_vector;
WriteBarrier<Unknown>* currentSource = butterfly->arrayStorage()->m_vector;
@@ -160,8 +159,7 @@ ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* but
// Mark the array if appropriate.
switch (structure->indexingType()) {
- case ArrayWithArrayStorage:
- case NonArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
visitor.appendValues(butterfly->arrayStorage()->m_vector, butterfly->arrayStorage()->vectorLength());
if (butterfly->arrayStorage()->m_sparseMap)
visitor.append(&butterfly->arrayStorage()->m_sparseMap);
@@ -234,12 +232,10 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned
return thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, Identifier::from(exec, i), slot);
switch (thisObject->structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
break;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
if (i >= storage->length())
return false;
@@ -301,7 +297,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV
unsigned attributes;
JSCell* specificValue;
PropertyOffset offset = obj->structure()->get(globalData, propertyName, attributes, specificValue);
- if (offset != invalidOffset) {
+ if (isValidOffset(offset)) {
if (attributes & ReadOnly) {
if (slot.isStrictMode())
throwError(exec, createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)));
@@ -347,15 +343,14 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
JSObject* thisObject = jsCast<JSObject*>(cell);
thisObject->checkIndexingConsistency();
- if (UNLIKELY(propertyName > MAX_ARRAY_INDEX)) {
+ if (propertyName > MAX_ARRAY_INDEX) {
PutPropertySlot slot(shouldThrow);
thisObject->methodTable()->put(thisObject, exec, Identifier::from(exec, propertyName), value, slot);
return;
}
switch (thisObject->structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
break;
case NonArrayWithArrayStorage:
@@ -381,6 +376,34 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName,
return;
}
+ case NonArrayWithSlowPutArrayStorage:
+ case ArrayWithSlowPutArrayStorage: {
+ ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
+
+ if (propertyName >= storage->vectorLength())
+ break;
+
+ WriteBarrier<Unknown>& valueSlot = storage->m_vector[propertyName];
+ unsigned length = storage->length();
+
+ // Update length & m_numValuesInVector as necessary.
+ if (propertyName >= length) {
+ if (thisObject->attemptToInterceptPutByIndexOnHole(exec, propertyName, value, shouldThrow))
+ return;
+ length = propertyName + 1;
+ storage->setLength(length);
+ ++storage->m_numValuesInVector;
+ } else if (!valueSlot) {
+ if (thisObject->attemptToInterceptPutByIndexOnHole(exec, propertyName, value, shouldThrow))
+ return;
+ ++storage->m_numValuesInVector;
+ }
+
+ valueSlot.set(exec->globalData(), thisObject, value);
+ thisObject->checkIndexingConsistency();
+ return;
+ }
+
default:
ASSERT_NOT_REACHED();
}
@@ -425,8 +448,7 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists
void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ArrayWithArrayStorage:
- case NonArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
break;
@@ -435,10 +457,23 @@ void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData)
}
}
+void JSObject::notifyPresenceOfIndexedAccessors(JSGlobalData& globalData)
+{
+ if (mayInterceptIndexedAccesses())
+ return;
+
+ setStructure(globalData, Structure::nonPropertyTransition(globalData, structure(), AddIndexedAccessors));
+
+ if (!mayBeUsedAsPrototype(globalData))
+ return;
+
+ globalObject()->haveABadTime(globalData);
+}
+
ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned length, unsigned vectorLength)
{
IndexingType oldType = structure()->indexingType();
- ASSERT_UNUSED(oldType, oldType == NonArray || oldType == ArrayClass);
+ ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType));
Butterfly* newButterfly = m_butterfly->growArrayRight(
globalData, structure(), structure()->outOfLineCapacity(), false, 0,
ArrayStorage::sizeFor(vectorLength));
@@ -454,7 +489,7 @@ ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned le
result->m_initializationIndex = 0;
result->m_inCompactInitialization = 0;
#endif
- Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateArrayStorage);
+ Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), structure()->suggestedIndexingTransition());
setButterfly(globalData, newButterfly, newStructure);
return result;
}
@@ -467,12 +502,10 @@ ArrayStorage* JSObject::createInitialArrayStorage(JSGlobalData& globalData)
ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ArrayWithArrayStorage:
- case NonArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage());
- case ArrayClass:
- case NonArray: {
+ case ALL_BLANK_INDEXING_TYPES: {
createArrayStorage(globalData, 0, 0);
SparseArrayValueMap* map = allocateSparseIndexMap(globalData);
map->setSparseMode();
@@ -485,6 +518,22 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J
}
}
+void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData)
+{
+ switch (structure()->indexingType()) {
+ case NonArrayWithArrayStorage:
+ case ArrayWithArrayStorage: {
+ Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), SwitchToSlowPutArrayStorage);
+ setStructure(globalData, newStructure);
+ break;
+ }
+
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
void JSObject::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes)
{
ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
@@ -492,6 +541,33 @@ void JSObject::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName
object->putDirectInternal<PutModeDefineOwnProperty>(exec->globalData(), propertyName, value, attributes, slot, getCallableObject(value));
}
+void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype)
+{
+ ASSERT(prototype);
+ if (prototype.isObject())
+ asObject(prototype)->notifyUsedAsPrototype(globalData);
+
+ Structure* newStructure = Structure::changePrototypeTransition(globalData, structure(), prototype);
+ setStructure(globalData, newStructure);
+
+ if (!newStructure->anyObjectInChainMayInterceptIndexedAccesses())
+ return;
+
+ if (mayBeUsedAsPrototype(globalData)) {
+ newStructure->globalObject()->haveABadTime(globalData);
+ return;
+ }
+
+ if (!hasIndexingHeader(structure()->indexingType()))
+ return;
+
+ if (shouldUseSlowPut(structure()->indexingType()))
+ return;
+
+ newStructure = Structure::nonPropertyTransition(globalData, newStructure, SwitchToSlowPutArrayStorage);
+ setStructure(globalData, newStructure);
+}
+
bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype)
{
JSValue checkFor = this;
@@ -508,9 +584,32 @@ bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prot
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 = isGlobalThis() ? jsCast<JSGlobalThis*>(this)->unwrappedObject() : this->globalObject();
+ JSGlobalObject* globalObject = unwrappedGlobalObject();
return globalObject->globalObjectMethodTable()->allowsAccessFrom(globalObject, exec);
}
@@ -597,12 +696,10 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
return thisObject->methodTable()->deleteProperty(thisObject, exec, Identifier::from(exec, i));
switch (thisObject->structure()->indexingType()) {
- case ArrayClass:
- case NonArray:
+ case ALL_BLANK_INDEXING_TYPES:
return true;
- case ArrayWithArrayStorage:
- case NonArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = thisObject->m_butterfly->arrayStorage();
if (i < storage->vectorLength()) {
@@ -762,12 +859,10 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa
// is incredibly inefficient for large arrays. We need a different approach,
// which almost certainly means a different structure for PropertyNameArray.
switch (object->structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
break;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = object->m_butterfly->arrayStorage();
unsigned usedVectorLength = std::min(storage->length(), storage->vectorLength());
@@ -857,6 +952,13 @@ void JSObject::preventExtensions(JSGlobalData& globalData)
setStructure(globalData, Structure::preventExtensionsTransition(globalData, structure()));
}
+JSGlobalObject* JSObject::unwrappedGlobalObject()
+{
+ if (isGlobalThis())
+ return jsCast<JSGlobalThis*>(this)->unwrappedObject();
+ return structure()->globalObject();
+}
+
// This presently will flatten to an uncachable dictionary; this is suitable
// for use in delete, we may want to do something different elsewhere.
void JSObject::reifyStaticFunctionsForDelete(ExecState* exec)
@@ -920,18 +1022,35 @@ NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, PropertyO
slot.setUndefined();
}
-Structure* JSObject::createInheritorID(JSGlobalData& globalData)
+void JSObject::notifyUsedAsPrototype(JSGlobalData& globalData)
{
- ASSERT(!getDirectLocation(globalData, globalData.m_inheritorIDKey));
-
- JSGlobalObject* globalObject;
- if (isGlobalThis())
- globalObject = static_cast<JSGlobalThis*>(this)->unwrappedObject();
- else
- globalObject = structure()->globalObject();
- ASSERT(globalObject);
+ 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* inheritorID = createEmptyObjectStructure(globalData, globalObject, this);
+Structure* JSObject::createInheritorID(JSGlobalData& globalData)
+{
+ Structure* inheritorID = createEmptyObjectStructure(globalData, unwrappedGlobalObject(), this);
ASSERT(inheritorID->isEmpty());
PutPropertySlot slot;
@@ -980,7 +1099,10 @@ void JSObject::putIndexedDescriptor(ExecState* exec, SparseArrayEntry* entryInMa
// Defined in ES5.1 8.12.9
bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, PropertyDescriptor& descriptor, bool throwException)
{
- ASSERT(index != 0xFFFFFFFF);
+ ASSERT(index <= MAX_ARRAY_INDEX);
+
+ if (descriptor.attributes() & (ReadOnly | Accessor))
+ notifyPresenceOfIndexedAccessors(exec->globalData());
if (!inSparseIndexingMode()) {
// Fast case: we're putting a regular property to a regular array
@@ -1109,6 +1231,40 @@ void JSObject::deallocateSparseIndexMap()
arrayStorage->m_sparseMap.clear();
}
+bool JSObject::attemptToInterceptPutByIndexOnHoleForPrototype(ExecState* exec, JSValue thisValue, unsigned i, JSValue value, bool shouldThrow)
+{
+ for (JSObject* current = this; ;) {
+ // This has the same behavior with respect to prototypes as JSObject::put(). It only
+ // allows a prototype to intercept a put if (a) the prototype declares the property
+ // we're after rather than intercepting it via an override of JSObject::put(), and
+ // (b) that property is declared as ReadOnly or Accessor.
+
+ ArrayStorage* storage = current->arrayStorageOrNull();
+ if (storage && storage->m_sparseMap) {
+ SparseArrayValueMap::iterator iter = storage->m_sparseMap->find(i);
+ if (iter != storage->m_sparseMap->notFound() && (iter->second.attributes & (Accessor | ReadOnly))) {
+ iter->second.put(exec, thisValue, storage->m_sparseMap.get(), value, shouldThrow);
+ return true;
+ }
+ }
+
+ JSValue prototypeValue = current->prototype();
+ if (prototypeValue.isNull())
+ return false;
+
+ current = asObject(prototypeValue);
+ }
+}
+
+bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
+{
+ JSValue prototypeValue = prototype();
+ if (prototypeValue.isNull())
+ return false;
+
+ return asObject(prototypeValue)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, this, i, value, shouldThrow);
+}
+
void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, ArrayStorage* storage)
{
JSGlobalData& globalData = exec->globalData();
@@ -1189,8 +1345,7 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue
ASSERT(i <= MAX_ARRAY_INDEX);
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass: {
+ case ALL_BLANK_INDEXING_TYPES: {
if (indexingShouldBeSparse()) {
putByIndexBeyondVectorLengthWithArrayStorage(exec, i, value, shouldThrow, ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
break;
@@ -1205,6 +1360,12 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue
storage->m_numValuesInVector = 1;
break;
}
+
+ case NonArrayWithSlowPutArrayStorage:
+ case ArrayWithSlowPutArrayStorage:
+ if (attemptToInterceptPutByIndexOnHole(exec, i, value, shouldThrow))
+ return;
+ // Otherwise, fall though.
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage:
@@ -1297,9 +1458,11 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
// 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);
+
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass: {
+ case ALL_BLANK_INDEXING_TYPES: {
if (indexingShouldBeSparse() || attributes)
return putDirectIndexBeyondVectorLengthWithArrayStorage(exec, i, value, attributes, mode, ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData));
if (!isDenseEnoughForVector(i, 0) || i >= MAX_STORAGE_VECTOR_LENGTH)
@@ -1311,8 +1474,7 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV
return true;
}
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return putDirectIndexBeyondVectorLengthWithArrayStorage(exec, i, value, attributes, mode, arrayStorage());
default:
@@ -1354,13 +1516,11 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength)
unsigned length;
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
vectorLength = 0;
length = 0;
break;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
vectorLength = m_butterfly->arrayStorage()->vectorLength();
length = m_butterfly->arrayStorage()->length();
break;
@@ -1478,12 +1638,10 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope
return false;
switch (object->structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
return false;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = object->m_butterfly->arrayStorage();
if (i >= storage->length())
return false;
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 8df521b75..8b52915b6 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -118,7 +118,18 @@ namespace JSC {
bool setPrototypeWithCycleCheck(JSGlobalData&, JSValue prototype);
Structure* inheritorID(JSGlobalData&);
-
+ void notifyUsedAsPrototype(JSGlobalData&);
+
+ bool mayBeUsedAsPrototype(JSGlobalData& globalData)
+ {
+ return isValidOffset(structure()->get(globalData, globalData.m_inheritorIDKey));
+ }
+
+ bool mayInterceptIndexedAccesses()
+ {
+ return structure()->mayInterceptIndexedAccesses();
+ }
+
JSValue get(ExecState*, PropertyName) const;
JSValue get(ExecState*, unsigned propertyName) const;
@@ -135,11 +146,9 @@ namespace JSC {
unsigned getArrayLength() const
{
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
return 0;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->length();
default:
ASSERT_NOT_REACHED();
@@ -150,11 +159,9 @@ namespace JSC {
unsigned getVectorLength()
{
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
return 0;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->vectorLength();
default:
ASSERT_NOT_REACHED();
@@ -189,11 +196,9 @@ namespace JSC {
bool canGetIndexQuickly(unsigned i)
{
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
return false;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return i < m_butterfly->arrayStorage()->vectorLength() && m_butterfly->arrayStorage()->m_vector[i];
default:
ASSERT_NOT_REACHED();
@@ -204,8 +209,7 @@ namespace JSC {
JSValue getIndexQuickly(unsigned i)
{
switch (structure()->indexingType()) {
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->m_vector[i].get();
default:
ASSERT_NOT_REACHED();
@@ -216,12 +220,15 @@ namespace JSC {
bool canSetIndexQuickly(unsigned i)
{
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
return false;
case NonArrayWithArrayStorage:
case ArrayWithArrayStorage:
return i < m_butterfly->arrayStorage()->vectorLength();
+ case NonArrayWithSlowPutArrayStorage:
+ case ArrayWithSlowPutArrayStorage:
+ return i < m_butterfly->arrayStorage()->vectorLength()
+ && !!m_butterfly->arrayStorage()->m_vector[i];
default:
ASSERT_NOT_REACHED();
return false;
@@ -231,8 +238,7 @@ namespace JSC {
void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
WriteBarrier<Unknown>& x = m_butterfly->arrayStorage()->m_vector[i];
if (!x) {
ArrayStorage* storage = m_butterfly->arrayStorage();
@@ -251,8 +257,7 @@ namespace JSC {
void initializeIndex(JSGlobalData& globalData, unsigned i, JSValue v)
{
switch (structure()->indexingType()) {
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
#if CHECK_ARRAY_CONSISTENCY
ASSERT(storage->m_inCompactInitialization);
@@ -276,8 +281,7 @@ namespace JSC {
void completeInitialization(unsigned newLength)
{
switch (structure()->indexingType()) {
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage: {
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
ArrayStorage* storage = m_butterfly->arrayStorage();
// Check that we have initialized as meny properties as we think we have.
UNUSED_PARAM(storage);
@@ -298,11 +302,9 @@ namespace JSC {
bool inSparseIndexingMode()
{
switch (structure()->indexingType()) {
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
return false;
- case NonArrayWithArrayStorage:
- case ArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage()->inSparseMode();
default:
ASSERT_NOT_REACHED();
@@ -487,6 +489,22 @@ namespace JSC {
return structure()->globalObject();
}
+ // Does everything possible to return the global object. If it encounters an object
+ // that does not have a global object, it returns 0 instead (for example
+ // JSNotAnObject).
+ JSGlobalObject* unwrappedGlobalObject();
+
+ void switchToSlowPutArrayStorage(JSGlobalData&);
+
+ // The receiver is the prototype in this case. The following:
+ //
+ // asObject(foo->structure()->storedPrototype())->attemptToInterceptPutByIndexOnHoleForPrototype(...)
+ //
+ // is equivalent to:
+ //
+ // foo->attemptToInterceptPutByIndexOnHole(...);
+ bool attemptToInterceptPutByIndexOnHoleForPrototype(ExecState*, JSValue thisValue, unsigned propertyName, JSValue, bool shouldThrow);
+
static size_t offsetOfInlineStorage();
static ptrdiff_t butterflyOffset()
@@ -522,10 +540,7 @@ namespace JSC {
// To create derived types you likely want JSNonFinalObject, below.
JSObject(JSGlobalData&, Structure*, Butterfly* = 0);
- void resetInheritorID(JSGlobalData& globalData)
- {
- removeDirect(globalData, globalData.m_inheritorIDKey);
- }
+ void resetInheritorID(JSGlobalData&);
void visitButterfly(SlotVisitor&, Butterfly*, size_t storageSize);
@@ -533,7 +548,7 @@ namespace JSC {
// storage. This will assert otherwise.
ArrayStorage* arrayStorage()
{
- ASSERT(structure()->indexingType() | HasArrayStorage);
+ ASSERT(hasArrayStorage(structure()->indexingType()));
return m_butterfly->arrayStorage();
}
@@ -542,8 +557,7 @@ namespace JSC {
ArrayStorage* arrayStorageOrNull()
{
switch (structure()->indexingType()) {
- case ArrayWithArrayStorage:
- case NonArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage();
default:
@@ -558,12 +572,10 @@ namespace JSC {
ArrayStorage* ensureArrayStorage(JSGlobalData& globalData)
{
switch (structure()->indexingType()) {
- case ArrayWithArrayStorage:
- case NonArrayWithArrayStorage:
+ case ALL_ARRAY_STORAGE_INDEXING_TYPES:
return m_butterfly->arrayStorage();
- case NonArray:
- case ArrayClass:
+ case ALL_BLANK_INDEXING_TYPES:
return createInitialArrayStorage(globalData);
default:
@@ -592,6 +604,10 @@ namespace JSC {
void deallocateSparseIndexMap();
bool defineOwnIndexedProperty(ExecState*, unsigned, PropertyDescriptor&, bool throwException);
SparseArrayValueMap* allocateSparseIndexMap(JSGlobalData&);
+
+ void notifyPresenceOfIndexedAccessors(JSGlobalData&);
+
+ bool attemptToInterceptPutByIndexOnHole(ExecState*, unsigned index, JSValue, bool shouldThrow);
private:
friend class LLIntOffsetsExtractor;
@@ -824,22 +840,6 @@ inline JSValue JSObject::prototype() const
return structure()->storedPrototype();
}
-inline void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype)
-{
- ASSERT(prototype);
- setStructure(globalData, Structure::changePrototypeTransition(globalData, structure(), prototype));
-}
-
-inline Structure* JSObject::inheritorID(JSGlobalData& globalData)
-{
- if (WriteBarrierBase<Unknown>* location = getDirectLocation(globalData, globalData.m_inheritorIDKey)) {
- Structure* inheritorID = jsCast<Structure*>(location->get());
- ASSERT(inheritorID->isEmpty());
- return inheritorID;
- }
- return createInheritorID(globalData);
-}
-
inline bool JSCell::inherits(const ClassInfo* info) const
{
return classInfo()->isSubClassOf(info);
@@ -1190,8 +1190,7 @@ inline void JSValue::put(ExecState* exec, PropertyName propertyName, JSValue val
inline void JSValue::putByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
{
if (UNLIKELY(!isCell())) {
- PutPropertySlot slot(shouldThrow);
- putToPrimitive(exec, Identifier::from(exec, propertyName), value, slot);
+ putToPrimitiveByIndex(exec, propertyName, value, shouldThrow);
return;
}
asCell()->methodTable()->putByIndex(asCell(), exec, propertyName, value, shouldThrow);
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp
index caff9973b..ac00fad3d 100644
--- a/Source/JavaScriptCore/runtime/JSValue.cpp
+++ b/Source/JavaScriptCore/runtime/JSValue.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, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2007, 2008, 2012 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -113,6 +113,12 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
{
JSGlobalData& globalData = exec->globalData();
+ unsigned index = propertyName.asIndex();
+ if (index != PropertyName::NotAnIndex) {
+ putToPrimitiveByIndex(exec, index, value, slot.isStrictMode());
+ return;
+ }
+
// Check if there are any setters or getters in the prototype chain
JSObject* obj = synthesizePrototype(exec);
JSValue prototype;
@@ -172,6 +178,21 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue
return;
}
+void JSValue::putToPrimitiveByIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
+{
+ if (propertyName > MAX_ARRAY_INDEX) {
+ PutPropertySlot slot(shouldThrow);
+ putToPrimitive(exec, Identifier::from(exec, propertyName), value, slot);
+ return;
+ }
+
+ if (synthesizePrototype(exec)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, *this, propertyName, value, shouldThrow))
+ return;
+
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+}
+
char* JSValue::description() const
{
static const size_t size = 128;
diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h
index ce9405817..6e01d8d2d 100644
--- a/Source/JavaScriptCore/runtime/JSValue.h
+++ b/Source/JavaScriptCore/runtime/JSValue.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, 2004, 2005, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 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
@@ -240,6 +240,7 @@ namespace JSC {
JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
void put(ExecState*, PropertyName, JSValue, PutPropertySlot&);
void putToPrimitive(ExecState*, PropertyName, JSValue, PutPropertySlot&);
+ void putToPrimitiveByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
void putByIndex(ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
JSObject* toThisObject(ExecState*) const;
diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
index 84c60a69c..b1a5b9fb3 100644
--- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -74,6 +74,7 @@ void ObjectPrototype::finishCreation(JSGlobalData& globalData, JSGlobalObject*)
{
Base::finishCreation(globalData);
ASSERT(inherits(&s_info));
+ notifyUsedAsPrototype(globalData);
}
bool ObjectPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot)
diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
index ed8aace66..04fea60e8 100644
--- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp
@@ -27,7 +27,6 @@
#include "RegExpMatchesArray.h"
#include "ButterflyInlineMethods.h"
-#include "SparseArrayValueMapInlineMethods.h"
namespace JSC {
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
index 40c4ed26e..3f709b0a7 100644
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
+++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp
@@ -27,11 +27,186 @@
#include "SparseArrayValueMap.h"
#include "ClassInfo.h"
-#include "SparseArrayValueMapInlineMethods.h"
+#include "GetterSetter.h"
+#include "JSObject.h"
+#include "PropertySlot.h"
+#include "Reject.h"
+#include "SlotVisitor.h"
+#include "Structure.h"
namespace JSC {
const ClassInfo SparseArrayValueMap::s_info = { "SparseArrayValueMap", 0, 0, 0, CREATE_METHOD_TABLE(SparseArrayValueMap) };
+SparseArrayValueMap::SparseArrayValueMap(JSGlobalData& globalData)
+ : Base(globalData, globalData.sparseArrayValueMapStructure.get())
+ , m_flags(Normal)
+ , m_reportedCapacity(0)
+{
+}
+
+SparseArrayValueMap::~SparseArrayValueMap()
+{
+}
+
+void SparseArrayValueMap::finishCreation(JSGlobalData& globalData)
+{
+ Base::finishCreation(globalData);
+}
+
+SparseArrayValueMap* SparseArrayValueMap::create(JSGlobalData& globalData)
+{
+ SparseArrayValueMap* result = new (NotNull, allocateCell<SparseArrayValueMap>(globalData.heap)) SparseArrayValueMap(globalData);
+ result->finishCreation(globalData);
+ return result;
+}
+
+void SparseArrayValueMap::destroy(JSCell* cell)
+{
+ static_cast<SparseArrayValueMap*>(cell)->SparseArrayValueMap::~SparseArrayValueMap();
+}
+
+Structure* SparseArrayValueMap::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
+{
+ return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), &s_info);
+}
+
+SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigned i)
+{
+ SparseArrayEntry entry;
+ entry.setWithoutWriteBarrier(jsUndefined());
+
+ AddResult result = m_map.add(i, entry);
+ size_t capacity = m_map.capacity();
+ if (capacity != m_reportedCapacity) {
+ Heap::heap(array)->reportExtraMemoryCost((capacity - m_reportedCapacity) * (sizeof(unsigned) + sizeof(WriteBarrier<Unknown>)));
+ m_reportedCapacity = capacity;
+ }
+ return result;
+}
+
+void SparseArrayValueMap::putEntry(ExecState* exec, JSObject* array, unsigned i, JSValue value, bool shouldThrow)
+{
+ AddResult result = add(array, i);
+ SparseArrayEntry& entry = result.iterator->second;
+
+ // To save a separate find & add, we first always add to the sparse map.
+ // In the uncommon case that this is a new property, and the array is not
+ // extensible, this is not the right thing to have done - so remove again.
+ if (result.isNewEntry && !array->isExtensible()) {
+ remove(result.iterator);
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+ return;
+ }
+
+ entry.put(exec, array, this, value, shouldThrow);
+}
+
+bool SparseArrayValueMap::putDirect(ExecState* exec, JSObject* array, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode)
+{
+ AddResult result = add(array, i);
+ SparseArrayEntry& entry = result.iterator->second;
+
+ // To save a separate find & add, we first always add to the sparse map.
+ // In the uncommon case that this is a new property, and the array is not
+ // extensible, this is not the right thing to have done - so remove again.
+ if (mode != PutDirectIndexLikePutDirect && result.isNewEntry && !array->isExtensible()) {
+ remove(result.iterator);
+ return reject(exec, mode == PutDirectIndexShouldThrow, "Attempting to define property on object that is not extensible.");
+ }
+
+ entry.attributes = attributes;
+ entry.set(exec->globalData(), this, value);
+ return true;
+}
+
+void SparseArrayEntry::get(PropertySlot& slot) const
+{
+ JSValue value = Base::get();
+ ASSERT(value);
+
+ if (LIKELY(!value.isGetterSetter())) {
+ slot.setValue(value);
+ return;
+ }
+
+ JSObject* getter = asGetterSetter(value)->getter();
+ if (!getter) {
+ slot.setUndefined();
+ return;
+ }
+
+ slot.setGetterSlot(getter);
+}
+
+void SparseArrayEntry::get(PropertyDescriptor& descriptor) const
+{
+ descriptor.setDescriptor(Base::get(), attributes);
+}
+
+JSValue SparseArrayEntry::get(ExecState* exec, JSObject* array) const
+{
+ JSValue result = Base::get();
+ ASSERT(result);
+
+ if (LIKELY(!result.isGetterSetter()))
+ return result;
+
+ JSObject* getter = asGetterSetter(result)->getter();
+ if (!getter)
+ return jsUndefined();
+
+ CallData callData;
+ CallType callType = getter->methodTable()->getCallData(getter, callData);
+ return call(exec, getter, callType, callData, array, exec->emptyList());
+}
+
+void SparseArrayEntry::put(ExecState* exec, JSValue thisValue, SparseArrayValueMap* map, JSValue value, bool shouldThrow)
+{
+ if (!(attributes & Accessor)) {
+ if (attributes & ReadOnly) {
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+ return;
+ }
+
+ set(exec->globalData(), map, value);
+ return;
+ }
+
+ JSValue accessor = Base::get();
+ ASSERT(accessor.isGetterSetter());
+ JSObject* setter = asGetterSetter(accessor)->setter();
+
+ if (!setter) {
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
+ return;
+ }
+
+ CallData callData;
+ CallType callType = setter->methodTable()->getCallData(setter, callData);
+ MarkedArgumentBuffer args;
+ args.append(value);
+ call(exec, setter, callType, callData, thisValue, args);
+}
+
+JSValue SparseArrayEntry::getNonSparseMode() const
+{
+ ASSERT(!attributes);
+ return Base::get();
+}
+
+void SparseArrayValueMap::visitChildren(JSCell* thisObject, SlotVisitor& visitor)
+{
+ Base::visitChildren(thisObject, visitor);
+
+ SparseArrayValueMap* thisMap = jsCast<SparseArrayValueMap*>(thisObject);
+ iterator end = thisMap->m_map.end();
+ for (iterator it = thisMap->m_map.begin(); it != end; ++it)
+ visitor.append(&it->second);
+}
+
} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
index aafdf974f..5d8d0577a 100644
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
+++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h
@@ -36,6 +36,8 @@
namespace JSC {
+class SparseArrayValueMap;
+
struct SparseArrayEntry : public WriteBarrier<Unknown> {
typedef WriteBarrier<Unknown> Base;
@@ -44,6 +46,7 @@ struct SparseArrayEntry : public WriteBarrier<Unknown> {
JSValue get(ExecState*, JSObject*) const;
void get(PropertySlot&) const;
void get(PropertyDescriptor&) const;
+ void put(ExecState*, JSValue thisValue, SparseArrayValueMap*, JSValue, bool shouldThrow);
JSValue getNonSparseMode() const;
unsigned attributes;
diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMapInlineMethods.h b/Source/JavaScriptCore/runtime/SparseArrayValueMapInlineMethods.h
deleted file mode 100644
index f3ef32f46..000000000
--- a/Source/JavaScriptCore/runtime/SparseArrayValueMapInlineMethods.h
+++ /dev/null
@@ -1,203 +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. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (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 SparseArrayValueMapInlineMethods_h
-#define SparseArrayValueMapInlineMethods_h
-
-#include "GetterSetter.h"
-#include "Reject.h"
-#include "SparseArrayValueMap.h"
-
-namespace JSC {
-
-inline SparseArrayValueMap::SparseArrayValueMap(JSGlobalData& globalData)
- : Base(globalData, globalData.sparseArrayValueMapStructure.get())
- , m_flags(Normal)
- , m_reportedCapacity(0)
-{
-}
-
-inline SparseArrayValueMap::~SparseArrayValueMap()
-{
-}
-
-inline void SparseArrayValueMap::finishCreation(JSGlobalData& globalData)
-{
- Base::finishCreation(globalData);
-}
-
-inline SparseArrayValueMap* SparseArrayValueMap::create(JSGlobalData& globalData)
-{
- SparseArrayValueMap* result = new (NotNull, allocateCell<SparseArrayValueMap>(globalData.heap)) SparseArrayValueMap(globalData);
- result->finishCreation(globalData);
- return result;
-}
-
-inline void SparseArrayValueMap::destroy(JSCell* cell)
-{
- static_cast<SparseArrayValueMap*>(cell)->SparseArrayValueMap::~SparseArrayValueMap();
-}
-
-inline Structure* SparseArrayValueMap::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
-{
- return Structure::create(globalData, globalObject, prototype, TypeInfo(CompoundType, StructureFlags), &s_info);
-}
-
-inline SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigned i)
-{
- SparseArrayEntry entry;
- entry.setWithoutWriteBarrier(jsUndefined());
-
- AddResult result = m_map.add(i, entry);
- size_t capacity = m_map.capacity();
- if (capacity != m_reportedCapacity) {
- Heap::heap(array)->reportExtraMemoryCost((capacity - m_reportedCapacity) * (sizeof(unsigned) + sizeof(WriteBarrier<Unknown>)));
- m_reportedCapacity = capacity;
- }
- return result;
-}
-
-inline void SparseArrayValueMap::putEntry(ExecState* exec, JSObject* array, unsigned i, JSValue value, bool shouldThrow)
-{
- AddResult result = add(array, i);
- SparseArrayEntry& entry = result.iterator->second;
-
- // To save a separate find & add, we first always add to the sparse map.
- // In the uncommon case that this is a new property, and the array is not
- // extensible, this is not the right thing to have done - so remove again.
- if (result.isNewEntry && !array->isExtensible()) {
- remove(result.iterator);
- if (shouldThrow)
- throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
- return;
- }
-
- if (!(entry.attributes & Accessor)) {
- if (entry.attributes & ReadOnly) {
- if (shouldThrow)
- throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
- return;
- }
-
- entry.set(exec->globalData(), this, value);
- return;
- }
-
- JSValue accessor = entry.SparseArrayEntry::Base::get();
- ASSERT(accessor.isGetterSetter());
- JSObject* setter = asGetterSetter(accessor)->setter();
-
- if (!setter) {
- if (shouldThrow)
- throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
- return;
- }
-
- CallData callData;
- CallType callType = setter->methodTable()->getCallData(setter, callData);
- MarkedArgumentBuffer args;
- args.append(value);
- call(exec, setter, callType, callData, array, args);
-}
-
-inline bool SparseArrayValueMap::putDirect(ExecState* exec, JSObject* array, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode)
-{
- AddResult result = add(array, i);
- SparseArrayEntry& entry = result.iterator->second;
-
- // To save a separate find & add, we first always add to the sparse map.
- // In the uncommon case that this is a new property, and the array is not
- // extensible, this is not the right thing to have done - so remove again.
- if (mode != PutDirectIndexLikePutDirect && result.isNewEntry && !array->isExtensible()) {
- remove(result.iterator);
- return reject(exec, mode == PutDirectIndexShouldThrow, "Attempting to define property on object that is not extensible.");
- }
-
- entry.attributes = attributes;
- entry.set(exec->globalData(), this, value);
- return true;
-}
-
-inline void SparseArrayEntry::get(PropertySlot& slot) const
-{
- JSValue value = Base::get();
- ASSERT(value);
-
- if (LIKELY(!value.isGetterSetter())) {
- slot.setValue(value);
- return;
- }
-
- JSObject* getter = asGetterSetter(value)->getter();
- if (!getter) {
- slot.setUndefined();
- return;
- }
-
- slot.setGetterSlot(getter);
-}
-
-inline void SparseArrayEntry::get(PropertyDescriptor& descriptor) const
-{
- descriptor.setDescriptor(Base::get(), attributes);
-}
-
-inline JSValue SparseArrayEntry::get(ExecState* exec, JSObject* array) const
-{
- JSValue result = Base::get();
- ASSERT(result);
-
- if (LIKELY(!result.isGetterSetter()))
- return result;
-
- JSObject* getter = asGetterSetter(result)->getter();
- if (!getter)
- return jsUndefined();
-
- CallData callData;
- CallType callType = getter->methodTable()->getCallData(getter, callData);
- return call(exec, getter, callType, callData, array, exec->emptyList());
-}
-
-inline JSValue SparseArrayEntry::getNonSparseMode() const
-{
- ASSERT(!attributes);
- return Base::get();
-}
-
-inline void SparseArrayValueMap::visitChildren(JSCell* thisObject, SlotVisitor& visitor)
-{
- Base::visitChildren(thisObject, visitor);
-
- SparseArrayValueMap* thisMap = jsCast<SparseArrayValueMap*>(thisObject);
- iterator end = thisMap->m_map.end();
- for (iterator it = thisMap->m_map.begin(); it != end; ++it)
- visitor.append(&it->second);
-}
-
-} // namespace JSC
-
-#endif // SparseArrayValueMapInlineMethods_h
-
diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp
index c99c6dda4..a59a0860d 100644
--- a/Source/JavaScriptCore/runtime/Structure.cpp
+++ b/Source/JavaScriptCore/runtime/Structure.cpp
@@ -309,6 +309,30 @@ Structure* Structure::addPropertyTransitionToExistingStructure(Structure* struct
return 0;
}
+bool Structure::anyObjectInChainMayInterceptIndexedAccesses() const
+{
+ for (const Structure* current = this; ;) {
+ if (current->mayInterceptIndexedAccesses())
+ return true;
+
+ JSValue prototype = current->storedPrototype();
+ if (prototype.isNull())
+ return false;
+
+ current = asObject(prototype)->structure();
+ }
+}
+
+NonPropertyTransition Structure::suggestedIndexingTransition() const
+{
+ ASSERT(!hasIndexedProperties(indexingType()));
+
+ if (anyObjectInChainMayInterceptIndexedAccesses() || globalObject()->isHavingABadTime())
+ return AllocateSlowPutArrayStorage;
+
+ return AllocateArrayStorage;
+}
+
Structure* Structure::addPropertyTransition(JSGlobalData& globalData, 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
diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h
index 9303a0dbb..e77287b20 100644
--- a/Source/JavaScriptCore/runtime/Structure.h
+++ b/Source/JavaScriptCore/runtime/Structure.h
@@ -144,7 +144,16 @@ namespace JSC {
IndexingType indexingType() const { return m_indexingType & AllArrayTypes; }
IndexingType indexingTypeIncludingHistory() const { return m_indexingType; }
-
+
+ bool mayInterceptIndexedAccesses() const
+ {
+ return !!(indexingTypeIncludingHistory() & MayHaveIndexedAccessors);
+ }
+
+ bool anyObjectInChainMayInterceptIndexedAccesses() const;
+
+ NonPropertyTransition suggestedIndexingTransition() const;
+
JSGlobalObject* globalObject() const { return m_globalObject.get(); }
void setGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject) { m_globalObject.set(globalData, this, globalObject); }
diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
index 59e7e94f3..90cb6a4db 100644
--- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h
+++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h
@@ -43,7 +43,10 @@ static const unsigned FirstInternalAttribute = 1 << 6; // Use for transitions th
// Support for attributes used to indicate transitions not related to properties.
// If any of these are used, the string portion of the key should be 0.
enum NonPropertyTransition {
- AllocateArrayStorage
+ AllocateArrayStorage,
+ AllocateSlowPutArrayStorage,
+ SwitchToSlowPutArrayStorage,
+ AddIndexedAccessors
};
inline unsigned toAttributes(NonPropertyTransition transition)
@@ -56,6 +59,13 @@ inline IndexingType newIndexingType(IndexingType oldType, NonPropertyTransition
switch (transition) {
case AllocateArrayStorage:
return oldType | HasArrayStorage;
+ case AllocateSlowPutArrayStorage:
+ return oldType | HasSlowPutArrayStorage;
+ case SwitchToSlowPutArrayStorage:
+ ASSERT(oldType & HasArrayStorage);
+ return (oldType & ~HasArrayStorage) | HasSlowPutArrayStorage;
+ case AddIndexedAccessors:
+ return oldType | MayHaveIndexedAccessors;
default:
ASSERT_NOT_REACHED();
return oldType;
diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h
index f6f70c6b9..5427a009b 100644
--- a/Source/JavaScriptCore/runtime/SymbolTable.h
+++ b/Source/JavaScriptCore/runtime/SymbolTable.h
@@ -40,6 +40,23 @@ namespace JSC {
class Watchpoint;
class WatchpointSet;
+ struct SlowArgument {
+ enum Status {
+ Normal = 0,
+ Captured = 1,
+ Deleted = 2
+ };
+
+ SlowArgument()
+ : status(Normal)
+ , indexIfCaptured(0)
+ {
+ }
+
+ Status status;
+ int indexIfCaptured; // If status is 'Captured', indexIfCaptured is our index in the CallFrame.
+ };
+
static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
// The bit twiddling in this class assumes that every register index is a
@@ -357,9 +374,14 @@ namespace JSC {
int captureEnd() { return m_captureEnd; }
void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
+ 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:
@@ -379,8 +401,9 @@ namespace JSC {
CaptureMode m_captureMode;
int m_captureStart;
int m_captureEnd;
+
+ OwnArrayPtr<SlowArgument> m_slowArguments;
};
-
} // namespace JSC
#endif // SymbolTable_h