Changeset 205462 in webkit
- Timestamp:
- Sep 5, 2016, 6:02:22 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 23 added
- 1 deleted
- 291 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/array-storage-array-unshift.js (added)
-
JSTests/stress/contiguous-array-unshift.js (added)
-
JSTests/stress/double-array-unshift.js (added)
-
JSTests/stress/int32-array-unshift.js (added)
-
JSTests/stress/unshift-array-storage.js (added)
-
Source/JavaScriptCore/API/JSManagedValue.mm (modified) (1 diff)
-
Source/JavaScriptCore/API/JSTypedArray.cpp (modified) (1 diff)
-
Source/JavaScriptCore/API/ObjCCallbackFunction.mm (modified) (1 diff)
-
Source/JavaScriptCore/API/tests/testapi.mm (modified) (2 diffs)
-
Source/JavaScriptCore/CMakeLists.txt (modified) (6 diffs)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (modified) (47 diffs)
-
Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_implementation.py (modified) (1 diff)
-
Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_implementation.py (modified) (1 diff)
-
Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_implementation.py (modified) (1 diff)
-
Source/JavaScriptCore/assembler/AbstractMacroAssembler.h (modified) (1 diff)
-
Source/JavaScriptCore/assembler/MacroAssembler.h (modified) (1 diff)
-
Source/JavaScriptCore/assembler/MacroAssemblerARM64.h (modified) (1 diff)
-
Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.cpp (added)
-
Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h (modified) (6 diffs)
-
Source/JavaScriptCore/b3/B3BasicBlock.cpp (modified) (1 diff)
-
Source/JavaScriptCore/b3/B3BasicBlock.h (modified) (1 diff)
-
Source/JavaScriptCore/b3/B3DuplicateTails.cpp (modified) (1 diff)
-
Source/JavaScriptCore/b3/B3StackmapGenerationParams.h (modified) (1 diff)
-
Source/JavaScriptCore/b3/testb3.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bindings/ScriptValue.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/BytecodeRewriter.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/BytecodeUseDef.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/CallLinkInfo.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/CallLinkInfo.h (modified) (3 diffs)
-
Source/JavaScriptCore/bytecode/CallLinkStatus.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/CodeBlock.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/bytecode/CodeBlock.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/ExecutionCounter.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/Instruction.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h (modified) (2 diffs)
-
Source/JavaScriptCore/bytecode/Opcode.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/bytecode/PolymorphicAccess.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/StructureStubInfo.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/StructureStubInfo.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/SuperSampler.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/bytecode/SuperSampler.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/UnlinkedInstructionStream.cpp (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/UnlinkedInstructionStream.h (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h (modified) (8 diffs)
-
Source/JavaScriptCore/dfg/DFGOperations.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/dfg/DFGOperations.h (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (modified) (9 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (modified) (2 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (modified) (2 diffs)
-
Source/JavaScriptCore/ftl/FTLCompile.cpp (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (modified) (28 diffs)
-
Source/JavaScriptCore/ftl/FTLOutput.cpp (modified) (18 diffs)
-
Source/JavaScriptCore/ftl/FTLOutput.h (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLValueFromBlock.h (modified) (1 diff)
-
Source/JavaScriptCore/ftl/FTLWeightedTarget.h (modified) (2 diffs)
-
Source/JavaScriptCore/heap/CellContainer.h (added)
-
Source/JavaScriptCore/heap/CellContainerInlines.h (added)
-
Source/JavaScriptCore/heap/ConservativeRoots.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/heap/ConservativeRoots.h (modified) (5 diffs)
-
Source/JavaScriptCore/heap/CopyToken.h (modified) (2 diffs)
-
Source/JavaScriptCore/heap/FreeList.cpp (added)
-
Source/JavaScriptCore/heap/FreeList.h (added)
-
Source/JavaScriptCore/heap/GCTypeMap.h (added)
-
Source/JavaScriptCore/heap/Heap.cpp (modified) (65 diffs)
-
Source/JavaScriptCore/heap/Heap.h (modified) (17 diffs)
-
Source/JavaScriptCore/heap/HeapCell.h (modified) (2 diffs)
-
Source/JavaScriptCore/heap/HeapCellInlines.h (added)
-
Source/JavaScriptCore/heap/HeapInlines.h (modified) (8 diffs)
-
Source/JavaScriptCore/heap/HeapOperation.cpp (added)
-
Source/JavaScriptCore/heap/HeapOperation.h (modified) (1 diff)
-
Source/JavaScriptCore/heap/HeapUtil.h (added)
-
Source/JavaScriptCore/heap/IncrementalSweeper.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/heap/IncrementalSweeper.h (modified) (3 diffs)
-
Source/JavaScriptCore/heap/LargeAllocation.cpp (added)
-
Source/JavaScriptCore/heap/LargeAllocation.h (added)
-
Source/JavaScriptCore/heap/MarkedAllocator.cpp (modified) (8 diffs)
-
Source/JavaScriptCore/heap/MarkedAllocator.h (modified) (6 diffs)
-
Source/JavaScriptCore/heap/MarkedBlock.cpp (modified) (12 diffs)
-
Source/JavaScriptCore/heap/MarkedBlock.h (modified) (6 diffs)
-
Source/JavaScriptCore/heap/MarkedSpace.cpp (modified) (16 diffs)
-
Source/JavaScriptCore/heap/MarkedSpace.h (modified) (10 diffs)
-
Source/JavaScriptCore/heap/SlotVisitor.cpp (modified) (9 diffs)
-
Source/JavaScriptCore/heap/SlotVisitor.h (modified) (4 diffs)
-
Source/JavaScriptCore/heap/WeakBlock.cpp (modified) (8 diffs)
-
Source/JavaScriptCore/heap/WeakBlock.h (modified) (6 diffs)
-
Source/JavaScriptCore/heap/WeakSet.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/heap/WeakSet.h (modified) (7 diffs)
-
Source/JavaScriptCore/heap/WeakSetInlines.h (modified) (3 diffs)
-
Source/JavaScriptCore/inspector/InjectedScriptManager.cpp (modified) (1 diff)
-
Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp (modified) (1 diff)
-
Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp (modified) (1 diff)
-
Source/JavaScriptCore/inspector/ScriptDebugServer.cpp (modified) (1 diff)
-
Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp (modified) (1 diff)
-
Source/JavaScriptCore/interpreter/CachedCall.h (modified) (2 diffs)
-
Source/JavaScriptCore/interpreter/Interpreter.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/interpreter/Interpreter.h (modified) (3 diffs)
-
Source/JavaScriptCore/jit/AssemblyHelpers.h (modified) (3 diffs)
-
Source/JavaScriptCore/jit/CCallHelpers.h (modified) (2 diffs)
-
Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/jit/JIT.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/jit/JIT.h (modified) (2 diffs)
-
Source/JavaScriptCore/jit/JITExceptions.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITExceptions.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITOpcodes.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/jit/JITOperations.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/jit/JITOperations.h (modified) (6 diffs)
-
Source/JavaScriptCore/jit/JITPropertyAccess.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITThunks.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITThunks.h (modified) (1 diff)
-
Source/JavaScriptCore/jsc.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/llint/LLIntData.cpp (modified) (1 diff)
-
Source/JavaScriptCore/llint/LLIntExceptions.cpp (modified) (1 diff)
-
Source/JavaScriptCore/llint/LLIntThunks.cpp (modified) (1 diff)
-
Source/JavaScriptCore/llint/LLIntThunks.h (modified) (1 diff)
-
Source/JavaScriptCore/llint/LowLevelInterpreter.asm (modified) (2 diffs)
-
Source/JavaScriptCore/llint/LowLevelInterpreter.cpp (modified) (1 diff)
-
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm (modified) (11 diffs)
-
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (modified) (10 diffs)
-
Source/JavaScriptCore/parser/ModuleAnalyzer.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/parser/NodeConstructors.h (modified) (1 diff)
-
Source/JavaScriptCore/parser/Nodes.h (modified) (2 diffs)
-
Source/JavaScriptCore/profiler/ProfilerBytecode.cpp (modified) (1 diff)
-
Source/JavaScriptCore/profiler/ProfilerBytecode.h (modified) (1 diff)
-
Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ArrayConventions.cpp (added)
-
Source/JavaScriptCore/runtime/ArrayConventions.h (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/ArrayPrototype.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/runtime/ArrayStorage.h (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/AuxiliaryBarrier.h (added)
-
Source/JavaScriptCore/runtime/AuxiliaryBarrierInlines.h (added)
-
Source/JavaScriptCore/runtime/Butterfly.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/ButterflyInlines.h (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/ClonedArguments.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/CommonSlowPathsExceptions.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/CommonSlowPathsExceptions.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/DataView.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/DirectArguments.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ECMAScriptSpecInternalFunctions.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Error.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/Error.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ErrorInstance.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ErrorInstance.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Exception.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Exception.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/GeneratorPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/InternalFunction.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlCollator.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlNumberFormat.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IntlObject.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/IteratorPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSArray.cpp (modified) (10 diffs)
-
Source/JavaScriptCore/runtime/JSArray.h (modified) (7 diffs)
-
Source/JavaScriptCore/runtime/JSArrayBufferView.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSCInlines.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSCJSValue.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSCallee.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/JSCell.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSCell.h (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/JSCellInlines.h (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/JSFunction.cpp (modified) (24 diffs)
-
Source/JavaScriptCore/runtime/JSFunction.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSFunctionInlines.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSInternalPromise.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSInternalPromiseDeferred.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSInternalPromisePrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSJob.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSMapIterator.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSModuleRecord.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSObject.cpp (modified) (29 diffs)
-
Source/JavaScriptCore/runtime/JSObject.h (modified) (11 diffs)
-
Source/JavaScriptCore/runtime/JSObjectInlines.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSPromise.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSPromiseDeferred.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSPromisePrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSScope.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSScope.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSSetIterator.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSStringIterator.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSTypedArrayViewConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSWeakMap.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/JSWeakSet.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/MapConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/MapIteratorPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/MapPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/NativeStdFunctionCell.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Operations.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Options.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/Options.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/PropertyTable.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ProxyConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ProxyObject.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ProxyRevoke.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/RegExp.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/RegExp.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/RegExpConstructor.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/RegExpInlines.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/RegExpMatchesArray.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/RegExpPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/RuntimeType.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/SamplingProfiler.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/SetConstructor.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/SetIteratorPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/SetPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/StackFrame.cpp (added)
-
Source/JavaScriptCore/runtime/StackFrame.h (added)
-
Source/JavaScriptCore/runtime/StringConstructor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/StructureInlines.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/TemplateRegistry.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/TestRunnerUtils.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/TestRunnerUtils.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ThrowScope.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/TypeProfilerLog.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/TypeSet.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/VM.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/runtime/VM.h (modified) (5 diffs)
-
Source/JavaScriptCore/runtime/VMEntryScope.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/VMInlines.h (modified) (3 diffs)
-
Source/JavaScriptCore/runtime/WeakMapConstructor.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/WeakMapData.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/WeakMapPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/WeakSetConstructor.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/WeakSetPrototype.cpp (modified) (1 diff)
-
Source/JavaScriptCore/testRegExp.cpp (modified) (1 diff)
-
Source/JavaScriptCore/tools/JSDollarVM.cpp (modified) (1 diff)
-
Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp (modified) (1 diff)
-
Source/WTF/ChangeLog (modified) (1 diff)
-
Source/WTF/wtf/FastMalloc.cpp (modified) (4 diffs)
-
Source/WTF/wtf/FastMalloc.h (modified) (3 diffs)
-
Source/WTF/wtf/ParkingLot.cpp (modified) (1 diff)
-
Source/WTF/wtf/ParkingLot.h (modified) (4 diffs)
-
Source/WTF/wtf/ScopedLambda.h (modified) (1 diff)
-
Source/WTF/wtf/SentinelLinkedList.h (modified) (2 diffs)
-
Source/WTF/wtf/SimpleStats.h (modified) (3 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/ForwardingHeaders/heap/HeapInlines.h (added)
-
Source/WebCore/ForwardingHeaders/interpreter/Interpreter.h (deleted)
-
Source/WebCore/ForwardingHeaders/runtime/AuxiliaryBarrierInlines.h (added)
-
Source/WebCore/Modules/indexeddb/IDBCursorWithValue.cpp (modified) (1 diff)
-
Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp (modified) (1 diff)
-
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (modified) (1 diff)
-
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSApplePayPaymentAuthorizedEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSApplePayPaymentMethodSelectedEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSApplePayShippingContactSelectedEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSApplePayShippingMethodSelectedEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSClientRectCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSDOMBinding.cpp (modified) (2 diffs)
-
Source/WebCore/bindings/js/JSDOMBinding.h (modified) (1 diff)
-
Source/WebCore/bindings/js/JSDeviceMotionEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSDeviceOrientationEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSErrorEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSIDBIndexCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSPerformanceTimingCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSPopStateEventCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSWebGL2RenderingContextCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp (modified) (1 diff)
-
Source/WebCore/bindings/js/WorkerScriptController.cpp (modified) (1 diff)
-
Source/WebCore/contentextensions/ContentExtensionParser.cpp (modified) (1 diff)
-
Source/WebCore/dom/ErrorEvent.cpp (modified) (1 diff)
-
Source/WebCore/html/HTMLCanvasElement.cpp (modified) (1 diff)
-
Source/WebCore/html/MediaDocument.cpp (modified) (1 diff)
-
Source/WebCore/inspector/CommandLineAPIModule.cpp (modified) (1 diff)
-
Source/WebCore/loader/EmptyClients.cpp (modified) (1 diff)
-
Source/WebCore/page/CaptionUserPreferences.cpp (modified) (1 diff)
-
Source/WebCore/page/Frame.cpp (modified) (1 diff)
-
Source/WebCore/page/PageGroup.cpp (modified) (1 diff)
-
Source/WebCore/page/UserContentController.cpp (modified) (1 diff)
-
Source/WebCore/platform/mock/mediasource/MockBox.cpp (modified) (1 diff)
-
Source/WebCore/testing/GCObservation.cpp (modified) (1 diff)
-
Source/WebKit2/ChangeLog (modified) (1 diff)
-
Source/WebKit2/UIProcess/ViewGestureController.cpp (modified) (1 diff)
-
Source/WebKit2/UIProcess/WebPageProxy.cpp (modified) (1 diff)
-
Source/WebKit2/UIProcess/WebProcessPool.cpp (modified) (1 diff)
-
Source/WebKit2/UIProcess/WebProcessProxy.cpp (modified) (1 diff)
-
Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp (modified) (1 diff)
-
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp (modified) (2 diffs)
-
Source/bmalloc/ChangeLog (modified) (1 diff)
-
Source/bmalloc/bmalloc/Allocator.cpp (modified) (3 diffs)
-
Source/bmalloc/bmalloc/Allocator.h (modified) (3 diffs)
-
Source/bmalloc/bmalloc/Cache.h (modified) (3 diffs)
-
Source/bmalloc/bmalloc/bmalloc.h (modified) (2 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/DumpRenderTree/TestRunner.cpp (modified) (1 diff)
-
Tools/DumpRenderTree/mac/DumpRenderTree.mm (modified) (2 diffs)
-
Tools/Scripts/run-jsc-stress-tests (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r205389 r205462 1 2016-08-31 Filip Pizlo <fpizlo@apple.com> 2 3 Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression 4 https://bugs.webkit.org/show_bug.cgi?id=160125 5 6 Reviewed by Geoffrey Garen and Keith Miller. 7 8 Most of the things I did properly covered by existing tests, but I found some simple cases of 9 unshifting that had sketchy coverage. 10 11 * stress/array-storage-array-unshift.js: Added. 12 * stress/contiguous-array-unshift.js: Added. 13 * stress/double-array-unshift.js: Added. 14 * stress/int32-array-unshift.js: Added. 15 1 16 2016-09-02 Michael Saboff <msaboff@apple.com> 2 17 -
trunk/Source/JavaScriptCore/API/JSManagedValue.mm
r197563 r205462 214 214 215 215 JSC::JSValue jsValue = toJS(exec, [value JSValueRef]); 216 dataLog("Creating managed value with value ", jsValue, "\n"); 216 217 if (jsValue.isObject()) 217 218 m_weakValue.setObject(JSC::jsCast<JSC::JSObject*>(jsValue.asCell()), self); -
trunk/Source/JavaScriptCore/API/JSTypedArray.cpp
r205198 r205462 33 33 #include "Error.h" 34 34 #include "JSArrayBufferViewInlines.h" 35 #include "JSC JSValueInlines.h"35 #include "JSCInlines.h" 36 36 #include "JSDataView.h" 37 37 #include "JSGenericTypedArrayViewInlines.h" -
trunk/Source/JavaScriptCore/API/ObjCCallbackFunction.mm
r204912 r205462 32 32 #import "APICast.h" 33 33 #import "Error.h" 34 #import "JSCJSValueInlines.h"35 34 #import "JSCell.h" 36 #import "JSC ellInlines.h"35 #import "JSCInlines.h" 37 36 #import "JSContextInternal.h" 38 37 #import "JSWrapperMap.h" -
trunk/Source/JavaScriptCore/API/tests/testapi.mm
r202846 r205462 511 511 } 512 512 513 // This test is flaky. Since GC marks C stack and registers as roots conservatively,514 // objects not referenced logically can be accidentally marked and alive.515 // To avoid this situation as possible as we can,516 // 1. run this test first before stack is polluted,517 // 2. extract this test as a function to suppress stack height.518 static void testWeakValue()519 {520 @autoreleasepool {521 JSVirtualMachine *vm = [[JSVirtualMachine alloc] init];522 TestObject *testObject = [TestObject testObject];523 JSManagedValue *weakValue;524 @autoreleasepool {525 JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];526 context[@"testObject"] = testObject;527 weakValue = [[JSManagedValue alloc] initWithValue:context[@"testObject"]];528 }529 530 @autoreleasepool {531 JSContext *context = [[JSContext alloc] initWithVirtualMachine:vm];532 context[@"testObject"] = testObject;533 JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]);534 checkResult(@"weak value == nil", ![weakValue value]);535 checkResult(@"root is still alive", !context[@"testObject"].isUndefined);536 }537 }538 }539 540 513 static void testObjectiveCAPIMain() 541 514 { … … 1514 1487 NSLog(@"Testing Objective-C API"); 1515 1488 checkNegativeNSIntegers(); 1516 testWeakValue();1517 1489 testObjectiveCAPIMain(); 1518 1490 } -
trunk/Source/JavaScriptCore/CMakeLists.txt
r205418 r205462 67 67 assembler/MacroAssemblerARM.cpp 68 68 assembler/MacroAssemblerARMv7.cpp 69 assembler/MacroAssemblerCodeRef.cpp 69 70 assembler/MacroAssemblerPrinter.cpp 70 71 assembler/MacroAssemblerX86Common.cpp … … 448 449 heap/EdenGCActivityCallback.cpp 449 450 heap/FullGCActivityCallback.cpp 451 heap/FreeList.cpp 450 452 heap/GCActivityCallback.cpp 451 453 heap/GCLogging.cpp … … 455 457 heap/HeapCell.cpp 456 458 heap/HeapHelperPool.cpp 459 heap/HeapOperation.cpp 457 460 heap/HeapProfiler.cpp 458 461 heap/HeapSnapshot.cpp … … 463 466 heap/IncrementalSweeper.cpp 464 467 heap/JITStubRoutineSet.cpp 468 heap/LargeAllocation.cpp 465 469 heap/LiveObjectList.cpp 466 470 heap/MachineStackMarker.cpp … … 620 624 runtime/ArrayBufferView.cpp 621 625 runtime/ArrayConstructor.cpp 626 runtime/ArrayConventions.cpp 622 627 runtime/ArrayIteratorPrototype.cpp 623 628 runtime/ArrayPrototype.cpp … … 800 805 runtime/SmallStrings.cpp 801 806 runtime/SparseArrayValueMap.cpp 807 runtime/StackFrame.cpp 802 808 runtime/StrictEvalActivation.cpp 803 809 runtime/StringConstructor.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r205418 r205462 1 2016-08-31 Filip Pizlo <fpizlo@apple.com> 2 3 Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression 4 https://bugs.webkit.org/show_bug.cgi?id=160125 5 6 Reviewed by Geoffrey Garen and Keith Miller. 7 8 In order to make the GC concurrent (bug 149432), we would either need to enable concurrent 9 copying or we would need to not copy. Concurrent copying carries a 1-2% throughput overhead 10 from the barriers alone. Considering that MarkedSpace does a decent job of avoiding 11 fragmentation, it's unlikely that it's worth paying 1-2% throughput for copying. So, we want 12 to get rid of copied space. This change moves copied space's biggest client over to marked 13 space. 14 15 Moving butterflies to marked space means having them use the new Auxiliary HeapCell 16 allocation path. This is a fairly mechanical change, but it caused performance regressions 17 everywhere, so this change also fixes MarkedSpace's performance issues. 18 19 At a high level the mechanical changes are: 20 21 - We use AuxiliaryBarrier instead of CopyBarrier. 22 23 - We use tryAllocateAuxiliary instead of tryAllocateStorage. I got rid of the silly 24 CheckedBoolean stuff, since it's so much more trouble than it's worth. 25 26 - The JITs have to emit inlined marked space allocations instead of inline copy space 27 allocations. 28 29 - Everyone has to get used to zeroing their butterflies after allocation instead of relying 30 on them being pre-zeroed by the GC. Copied space would zero things for you, while marked 31 space doesn't. 32 33 That's about 1/3 of this change. But this led to performance problems, which I fixed with 34 optimizations that amounted to a major MarkedSpace rewrite: 35 36 - MarkedSpace always causes internal fragmentation for array allocations because the vector 37 length we choose when we resize usually leads to a cell size that doesn't correspond to any 38 size class. I got around this by making array allocations usually round up vectorLength to 39 the maximum allowed by the size class that we would have allocated in. Also, 40 ensureLengthSlow() and friends first make sure that the requested length can't just be 41 fulfilled with the current allocation size. This safeguard means that not every array 42 allocation has to do size class queries. For example, the fast path of new Array(length) 43 never does any size class queries, under the assumption that (1) the speed gained from 44 avoiding an ensureLengthSlow() call, which then just changes the vectorLength by doing the 45 size class query, is too small to offset the speed lost by doing the query on every 46 allocation and (2) new Array(length) is a pretty good hint that resizing is not very 47 likely. 48 49 - Size classes in MarkedSpace were way too precise, which led to external fragmentation. This 50 changes MarkedSpace size classes to use a linear progression for very small sizes followed 51 by a geometric progression that naturally transitions to a hyperbolic progression. We want 52 hyperbolic sizes when we get close to blockSize: for example the largest size we want is 53 payloadSize / 2 rounded down, to ensure we get exactly two cells with minimal slop. The 54 next size down should be payloadSize / 3 rounded down, and so on. After the last precise 55 size (80 bytes), we proceed using a geometric progression, but round up each size to 56 minimize slop at the end of the block. This naturally causes the geometric progression to 57 turn hyperbolic for large sizes. The size class configuration happens at VM start-up, so 58 it can be controlled with runtime options. I found that a base of 1.4 works pretty well. 59 60 - Large allocations caused massive internal fragmentation, since the smallest large 61 allocation had to use exactly blockSize, and the largest small allocation used 62 blockSize / 2. The next size up - the first large allocation size to require two blocks - 63 also had 50% internal fragmentation. This is because we required large allocations to be 64 blockSize aligned, so that MarkedBlock::blockFor() would work. I decided to rewrite all of 65 that. Cells no longer have to be owned by a MarkedBlock. They can now alternatively be 66 owned by a LargeAllocation. These two things are abstracted as CellContainer. You know that 67 a cell is owned by a LargeAllocation if the MarkedBlock::atomSize / 2 bit is set. 68 Basically, large allocations are deliberately misaligned by 8 bytes. This actually works 69 out great since (1) typed arrays won't use large allocations anyway since they have their 70 own malloc fallback and (2) large array butterflies already have a 8 byte header, which 71 means that the 8 byte base misalignment aligns the large array payload on a 16 byte 72 boundary. I took extreme care to make sure that the isLargeAllocation bit checks are as 73 rare as possible; for example, ExecState::vm() skips the check because we know that callees 74 must be small allocations. It's also possible to use template tricks to do one check for 75 cell container kind, and then invoke a function specialized for MarkedBlock or a function 76 specialized for LargeAllocation. LargeAllocation includes stubs for all MarkedBlock methods 77 that get used from functions that are template-specialized like this. That's mostly to 78 speed up the GC marking code. Most other code can use CellContainer API or HeapCell API 79 directly. That's another thing: HeapCell, the common base of JSCell and auxiliary 80 allocations, is now smart enough to do a lot of things for you, like HeapCell::vm(), 81 HeapCell::heap(), HeapCell::isLargeAllocation(), and HeapCell::cellContainer(). The size 82 cutoff for large allocations is runtime-configurable, so long as you don't choose something 83 so small that callees end up large. I found that 400 bytes is roughly optimal. This means 84 that the MarkedBlock size classes end up being: 85 86 16, 32, 48, 64, 80, 112, 160, 224, 320 87 88 The next size class would have been 432, but that's above the 400 byte cutoff. All of this 89 is configurable with --sizeClassProgression and --largeAllocationCutoff. You can see what 90 size classes you end up with by doing --dumpSizeClasses=true. 91 92 - Copied space uses 64KB blocks, while marked space used to use 16KB blocks. Allocating a lot 93 of stuff in 16KB blocks was slower than allocating it in 64KB blocks because the GC had a 94 lot of per-block overhead. I removed this overhead: It's now 2x faster to scan all 95 MarkedBlocks because the list that contains the interesting meta-data is allocated on the 96 side, for better locality during a sequential walk. It's no longer necessary to scan 97 MarkedBlocks to find WeakSets, since the sets of WeakSets for eden scan and full scan are 98 maintained on-the-fly. It's no longer necessary to scan all MarkedBlocks to clear mark 99 bits because we now use versioned mark bits: to clear then, just increment the 64-bit 100 heap version. It's no longer necessary to scan retired MarkedBlocks while allocating 101 because marking retires them on-the-fly. It's no longer necessary to sort all blocks in 102 the IncrementalSweeper's snapshot because blocks now know if they are in the snapshot. Put 103 together, these optimizations allowed me to reduce block size to 16KB without losing much 104 performance. There is some small perf loss on JetStream/splay, but not enough to hurt 105 JetStream overall. I tried reducing block sizes further, to 4KB, since that is a 106 progression on membuster. That's not possible yet, since there is still enough per-block 107 overhead yet that such a reduction hurts JetStream too much. I filed a bug about improving 108 this further: https://bugs.webkit.org/show_bug.cgi?id=161581. 109 110 - Even after all of that, copying butterflies was still faster because it allowed us to skip 111 sweeping dead space. A good GC allocates over dead bytes without explicitly freeing them, 112 so the GC pause is O(size of live), not O(size of live + dead). O(dead) is usually much 113 larger than O(live), especially in an eden collection. Copying satisfies this premise while 114 mark+sweep does not. So, I invented a new kind of allocator: bump'n'pop. Previously, our 115 MarkedSpace allocator was a freelist pop. That's simple and easy to inline but requires 116 that we walk the block to build a free list. This means walking dead space. The new 117 allocator allows totally free MarkedBlocks to simply set up a bump-pointer arena instead. 118 The allocator is a hybrid of bump-pointer and freelist pop. It tries bump first. The bump 119 pointer always bumps by cellSize, so the result of filling a block with bumping looks as if 120 we had used freelist popping to fill it. Additionally, each MarkedBlock now has a bit to 121 quickly tell if the block is entirely free. This makes sweeping O(1) whenever a MarkedBlock 122 is completely empty, which is the common case because of the generational hypothesis: the 123 number of objects that survive an eden collection is a tiny fraction of the number of 124 objects that had been allocated, and this fraction is so small that there are typically 125 fewer than one survivors per MarkedBlock. This change was enough to make this change a net 126 win over tip-of-tree. 127 128 - FTL now shares the same allocation fast paths as everything else, which is great, because 129 bump'n'pop has gnarly control flow. We don't really want B3 to have to think about that 130 control flow, since it won't be able to improve the machine code we write ourselves. GC 131 fast paths are best written in assembly. So, I've empowered B3 to have even better support 132 for Patchpoint terminals. It's now totally fine for a Patchpoint terminal to be non-Void. 133 So, the new FTL allocation fast paths are just Patchpoint terminals that call through to 134 AssemblyHelpers::emitAllocate(). B3 still reasons about things like constant-folding the 135 size class calculation and constant-hoisting the allocator. Also, I gave the FTL the 136 ability to constant-fold some allocator logic (in case we first assume that we're doing a 137 variable-length allocation but then realize that the length is known). I think it makes 138 sense to have constant folding rules in FTL::Output, or whatever the B3 IR builder is, 139 since this makes lowering easier (you can constant fold during lowering more easily) and it 140 reduces the amount of malloc traffic. In the future, we could teach B3 how to better 141 constant-fold this code. That would require allowing loads to be constant-folded, which is 142 doable but hella tricky. 143 144 - It used to be that if a logical object allocation required two physical allocations (first 145 the butterfly and then the cell), then the JIT would emit the code in such a way that a 146 failure in the second fast path would cause us to forget the successful first physical 147 allocation. This was pointlessly wasteful. It turns out that it's very cheap to devote a 148 register to storing either the butterfly or null, because the butterfly register is anyway 149 going to be free inside the first allocation. The only overhead here is zeroing the 150 butterfly register. With that in place, we can just pass the butterfly-or-null to the slow 151 path, which can then either allocate a butterfly or not. So now we never waste a successful 152 allocation. This patch implements such a solution both in DFG (where it's easy to do this 153 since we control registers already) and in FTL (where it's annoying, because mutable 154 "butterfly-or-null" variables are hard to say in SSA; also I realized that we had code 155 duplicated the JSArray allocation utility, so I deduplicated it). This came up because in 156 one version of this patch, this wastage would resonate with some Kraken benchmark: the 157 benchmark would always allocate N small things followed by one bigger thing. The problem 158 was I accidentally adjusted the various fixed overheads in MarkedBlock in such a way that 159 the JSObject size class, which both the small and big thing shared for their cell, could 160 hold exactly N cells per MarkedBlock. Then the benchmark would always call slow path when 161 it allocated the big thing. So, it would end up having to allocate the big thing's large 162 butterfly twice, every single time! Ouch! 163 164 - It used to be that we zeroed CopiedBlocks using memset, and so array allocations enjoyed 165 amortization of the cost of zeroing. This doesn't work anymore - it's now up to the client 166 of the allocator to initialize the object to whatever state they need. It used to be that 167 we would just use a dumb loop. I initially changed this so that we would end up in memset 168 for large allocations, but this didn't actually help performance that much. I got a much 169 better result by playing with different memsets written in assembly. First I wrote one 170 using non-temporal stores. That was a small speed-up over memset. Then I tried the classic 171 "rep stos" approach, and holy cow that version was fast. It's a ~20% speed-up on array 172 allocation microbenchmarks. So, this patch adds code paths to do "rep stos" on x86_64, or 173 memset, or use a loop, as appropriate, for both "contiguous" arrays (holes are zero) and 174 double arrays (holes are PNaN). Note that the JIT always emits either a loop or a flat slab 175 of stores (if the size is known), but those paths in the JIT won't trigger for 176 NewArrayWithSize() if the size is large, since that takes us to the 177 operationNewArrayWithSize() slow path, which calls into JSArray::create(). That's why the 178 optimizations here are all in JSArray::create() - that's the hot place for large arrays 179 that need to be filled with holes. 180 181 All of this put together gives us neutral perf on JetStream, membuster, and PLT3, a ~1% 182 regression on Speedometer, and up to a 4% regression Kraken. The Kraken regression is 183 because Kraken was allocating exactly 1024 element arrays at a rate of 400MB/sec. This is a 184 best-case scenario for bump allocation. I think that we should fix bmalloc to make up the 185 difference, but take the hit for now because it's a crazy corner case. By comparison, the 186 alternative approach of using a copy barrier would have cost us 1-2%. That's the real 187 apples-to-apples comparison if your premise is that we should have a concurrent GC. After we 188 finish removing copied space, we will be barrier-ready for concurrent GC: we already have a 189 marking barrier and we simply won't need a copying barrier. This change gets us there for 190 the purposes of our benchmarks, since the remaining clients of copied space are not very 191 important. On the other hand, if we keep copying, then getting barrier-ready would mean 192 adding back the copy barrier, which costs more perf. 193 194 We might get bigger speed-ups once we remove CopiedSpace altogether. That requires moving 195 typed arrays and a few other weird things over to Aux MarkedSpace. 196 197 This also includes some header sanitization. The introduction of AuxiliaryBarrier, HeapCell, 198 and CellContainer meant that I had to include those files from everywhere. Fortunately, 199 just including JSCInlines.h (instead of manually including the files that includes) is 200 usually enough. So, I made most of JSC's cpp files include JSCInlines.h, which is something 201 that we were already basically doing. In places where JSCInlines.h would be too much, I just 202 included HeapInlines.h. This got weird, because we previously included HeapInlines.h from 203 JSObject.h. That's bad because it led to some circular dependencies, so I fixed it - but that 204 meant having to manually include HeapInlines.h from the places that previously got it 205 implicitly via JSObject.h. But that led to more problems for some reason: I started getting 206 build errors because non-JSC files were having trouble including Opcode.h. That's just silly, 207 since Opcode.h is meant to be an internal JSC header. So, I made it an internal header and 208 made it impossible to include it from outside JSC. This was a lot of work, but it was 209 necessary to get the patch to build on all ports. It's also a net win. There were many places 210 in WebCore that were transitively including a *ton* of JSC headers just because of the 211 JSObject.h->HeapInlines.h edge and a bunch of dependency edges that arose from some public 212 (for WebCore) JSC headers needing Interpreter.h or Opcode.h for bad reasons. 213 214 * API/JSManagedValue.mm: 215 (-[JSManagedValue initWithValue:]): 216 * API/JSTypedArray.cpp: 217 * API/ObjCCallbackFunction.mm: 218 * API/tests/testapi.mm: 219 (testObjectiveCAPI): 220 (testWeakValue): Deleted. 221 * CMakeLists.txt: 222 * JavaScriptCore.xcodeproj/project.pbxproj: 223 * Scripts/builtins/builtins_generate_combined_implementation.py: 224 (BuiltinsCombinedImplementationGenerator.generate_secondary_header_includes): 225 * Scripts/builtins/builtins_generate_internals_wrapper_implementation.py: 226 (BuiltinsInternalsWrapperImplementationGenerator.generate_secondary_header_includes): 227 * Scripts/builtins/builtins_generate_separate_implementation.py: 228 (BuiltinsSeparateImplementationGenerator.generate_secondary_header_includes): 229 * assembler/AbstractMacroAssembler.h: 230 (JSC::AbstractMacroAssembler::JumpList::link): 231 (JSC::AbstractMacroAssembler::JumpList::linkTo): 232 * assembler/MacroAssembler.h: 233 * assembler/MacroAssemblerARM64.h: 234 (JSC::MacroAssemblerARM64::add32): 235 * assembler/MacroAssemblerCodeRef.cpp: Added. 236 (JSC::MacroAssemblerCodePtr::createLLIntCodePtr): 237 (JSC::MacroAssemblerCodePtr::dumpWithName): 238 (JSC::MacroAssemblerCodePtr::dump): 239 (JSC::MacroAssemblerCodeRef::createLLIntCodeRef): 240 (JSC::MacroAssemblerCodeRef::dump): 241 * assembler/MacroAssemblerCodeRef.h: 242 (JSC::MacroAssemblerCodePtr::createLLIntCodePtr): Deleted. 243 (JSC::MacroAssemblerCodePtr::dumpWithName): Deleted. 244 (JSC::MacroAssemblerCodePtr::dump): Deleted. 245 (JSC::MacroAssemblerCodeRef::createLLIntCodeRef): Deleted. 246 (JSC::MacroAssemblerCodeRef::dump): Deleted. 247 * b3/B3BasicBlock.cpp: 248 (JSC::B3::BasicBlock::appendBoolConstant): 249 * b3/B3BasicBlock.h: 250 * b3/B3DuplicateTails.cpp: 251 * b3/B3StackmapGenerationParams.h: 252 * b3/testb3.cpp: 253 (JSC::B3::testPatchpointTerminalReturnValue): 254 (JSC::B3::run): 255 * bindings/ScriptValue.cpp: 256 * bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp: 257 * bytecode/BytecodeBasicBlock.cpp: 258 * bytecode/BytecodeLivenessAnalysis.cpp: 259 * bytecode/BytecodeUseDef.h: 260 * bytecode/CallLinkInfo.cpp: 261 (JSC::CallLinkInfo::callTypeFor): 262 * bytecode/CallLinkInfo.h: 263 (JSC::CallLinkInfo::callTypeFor): Deleted. 264 * bytecode/CallLinkStatus.cpp: 265 * bytecode/CodeBlock.cpp: 266 (JSC::CodeBlock::finishCreation): 267 (JSC::CodeBlock::clearLLIntGetByIdCache): 268 (JSC::CodeBlock::predictedMachineCodeSize): 269 * bytecode/CodeBlock.h: 270 (JSC::CodeBlock::jitCodeMap): Deleted. 271 (JSC::clearLLIntGetByIdCache): Deleted. 272 * bytecode/ExecutionCounter.h: 273 * bytecode/Instruction.h: 274 * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp: 275 (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal): 276 * bytecode/ObjectAllocationProfile.h: 277 (JSC::ObjectAllocationProfile::isNull): 278 (JSC::ObjectAllocationProfile::initialize): 279 * bytecode/Opcode.h: 280 (JSC::padOpcodeName): 281 * bytecode/PolymorphicAccess.cpp: 282 (JSC::AccessCase::generateImpl): 283 (JSC::PolymorphicAccess::regenerate): 284 * bytecode/PolymorphicAccess.h: 285 * bytecode/PreciseJumpTargets.cpp: 286 * bytecode/StructureStubInfo.cpp: 287 * bytecode/StructureStubInfo.h: 288 * bytecode/UnlinkedCodeBlock.cpp: 289 (JSC::UnlinkedCodeBlock::vm): Deleted. 290 * bytecode/UnlinkedCodeBlock.h: 291 * bytecode/UnlinkedInstructionStream.cpp: 292 * bytecode/UnlinkedInstructionStream.h: 293 * dfg/DFGOperations.cpp: 294 * dfg/DFGSpeculativeJIT.cpp: 295 (JSC::DFG::SpeculativeJIT::emitAllocateRawObject): 296 (JSC::DFG::SpeculativeJIT::compileMakeRope): 297 (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): 298 (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): 299 * dfg/DFGSpeculativeJIT.h: 300 (JSC::DFG::SpeculativeJIT::emitAllocateJSCell): 301 (JSC::DFG::SpeculativeJIT::emitAllocateJSObject): 302 * dfg/DFGSpeculativeJIT32_64.cpp: 303 (JSC::DFG::SpeculativeJIT::compile): 304 (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): 305 * dfg/DFGSpeculativeJIT64.cpp: 306 (JSC::DFG::SpeculativeJIT::compile): 307 (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): 308 * dfg/DFGStrengthReductionPhase.cpp: 309 (JSC::DFG::StrengthReductionPhase::handleNode): 310 * ftl/FTLAbstractHeapRepository.h: 311 * ftl/FTLCompile.cpp: 312 * ftl/FTLJITFinalizer.cpp: 313 * ftl/FTLLowerDFGToB3.cpp: 314 (JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments): 315 (JSC::FTL::DFG::LowerDFGToB3::compileCreateRest): 316 (JSC::FTL::DFG::LowerDFGToB3::allocateArrayWithSize): 317 (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSize): 318 (JSC::FTL::DFG::LowerDFGToB3::compileMakeRope): 319 (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): 320 (JSC::FTL::DFG::LowerDFGToB3::initializeArrayElements): 321 (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl): 322 (JSC::FTL::DFG::LowerDFGToB3::allocateHeapCell): 323 (JSC::FTL::DFG::LowerDFGToB3::allocateCell): 324 (JSC::FTL::DFG::LowerDFGToB3::allocateObject): 325 (JSC::FTL::DFG::LowerDFGToB3::allocatorForSize): 326 (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedObject): 327 (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray): 328 (JSC::FTL::DFG::LowerDFGToB3::compileAllocateArrayWithSize): Deleted. 329 * ftl/FTLOutput.cpp: 330 (JSC::FTL::Output::constBool): 331 (JSC::FTL::Output::add): 332 (JSC::FTL::Output::shl): 333 (JSC::FTL::Output::aShr): 334 (JSC::FTL::Output::lShr): 335 (JSC::FTL::Output::zeroExt): 336 (JSC::FTL::Output::equal): 337 (JSC::FTL::Output::notEqual): 338 (JSC::FTL::Output::above): 339 (JSC::FTL::Output::aboveOrEqual): 340 (JSC::FTL::Output::below): 341 (JSC::FTL::Output::belowOrEqual): 342 (JSC::FTL::Output::greaterThan): 343 (JSC::FTL::Output::greaterThanOrEqual): 344 (JSC::FTL::Output::lessThan): 345 (JSC::FTL::Output::lessThanOrEqual): 346 (JSC::FTL::Output::select): 347 (JSC::FTL::Output::appendSuccessor): 348 (JSC::FTL::Output::addIncomingToPhi): 349 * ftl/FTLOutput.h: 350 * ftl/FTLValueFromBlock.h: 351 (JSC::FTL::ValueFromBlock::operator bool): 352 (JSC::FTL::ValueFromBlock::ValueFromBlock): Deleted. 353 * ftl/FTLWeightedTarget.h: 354 (JSC::FTL::WeightedTarget::frequentedBlock): 355 * heap/CellContainer.h: Added. 356 (JSC::CellContainer::CellContainer): 357 (JSC::CellContainer::operator bool): 358 (JSC::CellContainer::isMarkedBlock): 359 (JSC::CellContainer::isLargeAllocation): 360 (JSC::CellContainer::markedBlock): 361 (JSC::CellContainer::largeAllocation): 362 * heap/CellContainerInlines.h: Added. 363 (JSC::CellContainer::isMarked): 364 (JSC::CellContainer::isMarkedOrNewlyAllocated): 365 (JSC::CellContainer::noteMarked): 366 (JSC::CellContainer::cellSize): 367 (JSC::CellContainer::weakSet): 368 (JSC::CellContainer::flipIfNecessary): 369 * heap/ConservativeRoots.cpp: 370 (JSC::ConservativeRoots::ConservativeRoots): 371 (JSC::ConservativeRoots::~ConservativeRoots): 372 (JSC::ConservativeRoots::grow): 373 (JSC::ConservativeRoots::genericAddPointer): 374 (JSC::ConservativeRoots::genericAddSpan): 375 * heap/ConservativeRoots.h: 376 (JSC::ConservativeRoots::roots): 377 * heap/CopyToken.h: 378 * heap/FreeList.cpp: Added. 379 (JSC::FreeList::dump): 380 * heap/FreeList.h: Added. 381 (JSC::FreeList::FreeList): 382 (JSC::FreeList::list): 383 (JSC::FreeList::bump): 384 (JSC::FreeList::operator==): 385 (JSC::FreeList::operator!=): 386 (JSC::FreeList::operator bool): 387 (JSC::FreeList::allocationWillFail): 388 (JSC::FreeList::allocationWillSucceed): 389 * heap/GCTypeMap.h: Added. 390 (JSC::GCTypeMap::operator[]): 391 * heap/Heap.cpp: 392 (JSC::Heap::Heap): 393 (JSC::Heap::lastChanceToFinalize): 394 (JSC::Heap::finalizeUnconditionalFinalizers): 395 (JSC::Heap::markRoots): 396 (JSC::Heap::copyBackingStores): 397 (JSC::Heap::gatherStackRoots): 398 (JSC::Heap::gatherJSStackRoots): 399 (JSC::Heap::gatherScratchBufferRoots): 400 (JSC::Heap::clearLivenessData): 401 (JSC::Heap::visitSmallStrings): 402 (JSC::Heap::visitConservativeRoots): 403 (JSC::Heap::removeDeadCompilerWorklistEntries): 404 (JSC::Heap::gatherExtraHeapSnapshotData): 405 (JSC::Heap::removeDeadHeapSnapshotNodes): 406 (JSC::Heap::visitProtectedObjects): 407 (JSC::Heap::visitArgumentBuffers): 408 (JSC::Heap::visitException): 409 (JSC::Heap::visitStrongHandles): 410 (JSC::Heap::visitHandleStack): 411 (JSC::Heap::visitSamplingProfiler): 412 (JSC::Heap::traceCodeBlocksAndJITStubRoutines): 413 (JSC::Heap::converge): 414 (JSC::Heap::visitWeakHandles): 415 (JSC::Heap::updateObjectCounts): 416 (JSC::Heap::clearUnmarkedExecutables): 417 (JSC::Heap::deleteUnmarkedCompiledCode): 418 (JSC::Heap::collectAllGarbage): 419 (JSC::Heap::collect): 420 (JSC::Heap::collectWithoutAnySweep): 421 (JSC::Heap::collectImpl): 422 (JSC::Heap::suspendCompilerThreads): 423 (JSC::Heap::willStartCollection): 424 (JSC::Heap::flushOldStructureIDTables): 425 (JSC::Heap::flushWriteBarrierBuffer): 426 (JSC::Heap::stopAllocation): 427 (JSC::Heap::prepareForMarking): 428 (JSC::Heap::reapWeakHandles): 429 (JSC::Heap::pruneStaleEntriesFromWeakGCMaps): 430 (JSC::Heap::sweepArrayBuffers): 431 (JSC::MarkedBlockSnapshotFunctor::MarkedBlockSnapshotFunctor): 432 (JSC::MarkedBlockSnapshotFunctor::operator()): 433 (JSC::Heap::snapshotMarkedSpace): 434 (JSC::Heap::deleteSourceProviderCaches): 435 (JSC::Heap::notifyIncrementalSweeper): 436 (JSC::Heap::writeBarrierCurrentlyExecutingCodeBlocks): 437 (JSC::Heap::resetAllocators): 438 (JSC::Heap::updateAllocationLimits): 439 (JSC::Heap::didFinishCollection): 440 (JSC::Heap::resumeCompilerThreads): 441 (JSC::Zombify::visit): 442 (JSC::Heap::forEachCodeBlockImpl): 443 * heap/Heap.h: 444 (JSC::Heap::allocatorForObjectWithoutDestructor): 445 (JSC::Heap::allocatorForObjectWithDestructor): 446 (JSC::Heap::allocatorForAuxiliaryData): 447 (JSC::Heap::jitStubRoutines): 448 (JSC::Heap::codeBlockSet): 449 (JSC::Heap::storageAllocator): Deleted. 450 * heap/HeapCell.h: 451 (JSC::HeapCell::isZapped): Deleted. 452 * heap/HeapCellInlines.h: Added. 453 (JSC::HeapCell::isLargeAllocation): 454 (JSC::HeapCell::cellContainer): 455 (JSC::HeapCell::markedBlock): 456 (JSC::HeapCell::largeAllocation): 457 (JSC::HeapCell::heap): 458 (JSC::HeapCell::vm): 459 (JSC::HeapCell::cellSize): 460 (JSC::HeapCell::allocatorAttributes): 461 (JSC::HeapCell::destructionMode): 462 (JSC::HeapCell::cellKind): 463 * heap/HeapInlines.h: 464 (JSC::Heap::heap): 465 (JSC::Heap::isLive): 466 (JSC::Heap::isMarked): 467 (JSC::Heap::testAndSetMarked): 468 (JSC::Heap::setMarked): 469 (JSC::Heap::cellSize): 470 (JSC::Heap::forEachCodeBlock): 471 (JSC::Heap::allocateObjectOfType): 472 (JSC::Heap::subspaceForObjectOfType): 473 (JSC::Heap::allocatorForObjectOfType): 474 (JSC::Heap::allocateAuxiliary): 475 (JSC::Heap::tryAllocateAuxiliary): 476 (JSC::Heap::tryReallocateAuxiliary): 477 (JSC::Heap::isPointerGCObject): Deleted. 478 (JSC::Heap::isValueGCObject): Deleted. 479 * heap/HeapOperation.cpp: Added. 480 (WTF::printInternal): 481 * heap/HeapOperation.h: 482 * heap/HeapUtil.h: Added. 483 (JSC::HeapUtil::findGCObjectPointersForMarking): 484 (JSC::HeapUtil::isPointerGCObjectJSCell): 485 (JSC::HeapUtil::isValueGCObject): 486 * heap/IncrementalSweeper.cpp: 487 (JSC::IncrementalSweeper::sweepNextBlock): 488 * heap/IncrementalSweeper.h: 489 * heap/LargeAllocation.cpp: Added. 490 (JSC::LargeAllocation::tryCreate): 491 (JSC::LargeAllocation::LargeAllocation): 492 (JSC::LargeAllocation::lastChanceToFinalize): 493 (JSC::LargeAllocation::shrink): 494 (JSC::LargeAllocation::visitWeakSet): 495 (JSC::LargeAllocation::reapWeakSet): 496 (JSC::LargeAllocation::flip): 497 (JSC::LargeAllocation::isEmpty): 498 (JSC::LargeAllocation::sweep): 499 (JSC::LargeAllocation::destroy): 500 (JSC::LargeAllocation::dump): 501 * heap/LargeAllocation.h: Added. 502 (JSC::LargeAllocation::fromCell): 503 (JSC::LargeAllocation::cell): 504 (JSC::LargeAllocation::isLargeAllocation): 505 (JSC::LargeAllocation::heap): 506 (JSC::LargeAllocation::vm): 507 (JSC::LargeAllocation::weakSet): 508 (JSC::LargeAllocation::clearNewlyAllocated): 509 (JSC::LargeAllocation::isNewlyAllocated): 510 (JSC::LargeAllocation::isMarked): 511 (JSC::LargeAllocation::isMarkedOrNewlyAllocated): 512 (JSC::LargeAllocation::isLive): 513 (JSC::LargeAllocation::hasValidCell): 514 (JSC::LargeAllocation::cellSize): 515 (JSC::LargeAllocation::aboveLowerBound): 516 (JSC::LargeAllocation::belowUpperBound): 517 (JSC::LargeAllocation::contains): 518 (JSC::LargeAllocation::attributes): 519 (JSC::LargeAllocation::flipIfNecessary): 520 (JSC::LargeAllocation::flipIfNecessaryConcurrently): 521 (JSC::LargeAllocation::testAndSetMarked): 522 (JSC::LargeAllocation::setMarked): 523 (JSC::LargeAllocation::clearMarked): 524 (JSC::LargeAllocation::noteMarked): 525 (JSC::LargeAllocation::headerSize): 526 * heap/MarkedAllocator.cpp: 527 (JSC::MarkedAllocator::MarkedAllocator): 528 (JSC::MarkedAllocator::isPagedOut): 529 (JSC::MarkedAllocator::retire): 530 (JSC::MarkedAllocator::filterNextBlock): 531 (JSC::MarkedAllocator::setNextBlockToSweep): 532 (JSC::MarkedAllocator::tryAllocateWithoutCollectingImpl): 533 (JSC::MarkedAllocator::tryAllocateWithoutCollecting): 534 (JSC::MarkedAllocator::allocateSlowCase): 535 (JSC::MarkedAllocator::tryAllocateSlowCase): 536 (JSC::MarkedAllocator::allocateSlowCaseImpl): 537 (JSC::blockHeaderSize): 538 (JSC::MarkedAllocator::blockSizeForBytes): 539 (JSC::MarkedAllocator::tryAllocateBlock): 540 (JSC::MarkedAllocator::addBlock): 541 (JSC::MarkedAllocator::removeBlock): 542 (JSC::MarkedAllocator::stopAllocating): 543 (JSC::MarkedAllocator::reset): 544 (JSC::MarkedAllocator::lastChanceToFinalize): 545 (JSC::MarkedAllocator::setFreeList): 546 (JSC::isListPagedOut): Deleted. 547 (JSC::MarkedAllocator::tryAllocateHelper): Deleted. 548 (JSC::MarkedAllocator::tryPopFreeList): Deleted. 549 (JSC::MarkedAllocator::tryAllocate): Deleted. 550 (JSC::MarkedAllocator::allocateBlock): Deleted. 551 * heap/MarkedAllocator.h: 552 (JSC::MarkedAllocator::takeLastActiveBlock): 553 (JSC::MarkedAllocator::offsetOfFreeList): 554 (JSC::MarkedAllocator::offsetOfCellSize): 555 (JSC::MarkedAllocator::tryAllocate): 556 (JSC::MarkedAllocator::allocate): 557 (JSC::MarkedAllocator::forEachBlock): 558 (JSC::MarkedAllocator::offsetOfFreeListHead): Deleted. 559 (JSC::MarkedAllocator::MarkedAllocator): Deleted. 560 (JSC::MarkedAllocator::init): Deleted. 561 (JSC::MarkedAllocator::stopAllocating): Deleted. 562 * heap/MarkedBlock.cpp: 563 (JSC::MarkedBlock::tryCreate): 564 (JSC::MarkedBlock::Handle::Handle): 565 (JSC::MarkedBlock::Handle::~Handle): 566 (JSC::MarkedBlock::MarkedBlock): 567 (JSC::MarkedBlock::Handle::specializedSweep): 568 (JSC::MarkedBlock::Handle::sweep): 569 (JSC::MarkedBlock::Handle::sweepHelperSelectScribbleMode): 570 (JSC::MarkedBlock::Handle::sweepHelperSelectStateAndSweepMode): 571 (JSC::MarkedBlock::Handle::unsweepWithNoNewlyAllocated): 572 (JSC::SetNewlyAllocatedFunctor::SetNewlyAllocatedFunctor): 573 (JSC::SetNewlyAllocatedFunctor::operator()): 574 (JSC::MarkedBlock::Handle::stopAllocating): 575 (JSC::MarkedBlock::Handle::lastChanceToFinalize): 576 (JSC::MarkedBlock::Handle::resumeAllocating): 577 (JSC::MarkedBlock::Handle::zap): 578 (JSC::MarkedBlock::Handle::forEachFreeCell): 579 (JSC::MarkedBlock::flipIfNecessary): 580 (JSC::MarkedBlock::Handle::flipIfNecessary): 581 (JSC::MarkedBlock::flipIfNecessarySlow): 582 (JSC::MarkedBlock::flipIfNecessaryConcurrentlySlow): 583 (JSC::MarkedBlock::clearMarks): 584 (JSC::MarkedBlock::assertFlipped): 585 (JSC::MarkedBlock::needsFlip): 586 (JSC::MarkedBlock::Handle::needsFlip): 587 (JSC::MarkedBlock::Handle::willRemoveBlock): 588 (JSC::MarkedBlock::Handle::didConsumeFreeList): 589 (JSC::MarkedBlock::markCount): 590 (JSC::MarkedBlock::Handle::isEmpty): 591 (JSC::MarkedBlock::clearHasAnyMarked): 592 (JSC::MarkedBlock::noteMarkedSlow): 593 (WTF::printInternal): 594 (JSC::MarkedBlock::create): Deleted. 595 (JSC::MarkedBlock::destroy): Deleted. 596 (JSC::MarkedBlock::callDestructor): Deleted. 597 (JSC::MarkedBlock::specializedSweep): Deleted. 598 (JSC::MarkedBlock::sweep): Deleted. 599 (JSC::MarkedBlock::sweepHelper): Deleted. 600 (JSC::MarkedBlock::stopAllocating): Deleted. 601 (JSC::MarkedBlock::clearMarksWithCollectionType): Deleted. 602 (JSC::MarkedBlock::lastChanceToFinalize): Deleted. 603 (JSC::MarkedBlock::resumeAllocating): Deleted. 604 (JSC::MarkedBlock::didRetireBlock): Deleted. 605 * heap/MarkedBlock.h: 606 (JSC::MarkedBlock::VoidFunctor::returnValue): 607 (JSC::MarkedBlock::CountFunctor::CountFunctor): 608 (JSC::MarkedBlock::CountFunctor::count): 609 (JSC::MarkedBlock::CountFunctor::returnValue): 610 (JSC::MarkedBlock::Handle::hasAnyNewlyAllocated): 611 (JSC::MarkedBlock::Handle::isOnBlocksToSweep): 612 (JSC::MarkedBlock::Handle::setIsOnBlocksToSweep): 613 (JSC::MarkedBlock::Handle::state): 614 (JSC::MarkedBlock::needsDestruction): 615 (JSC::MarkedBlock::handle): 616 (JSC::MarkedBlock::Handle::block): 617 (JSC::MarkedBlock::firstAtom): 618 (JSC::MarkedBlock::atoms): 619 (JSC::MarkedBlock::isAtomAligned): 620 (JSC::MarkedBlock::Handle::cellAlign): 621 (JSC::MarkedBlock::blockFor): 622 (JSC::MarkedBlock::Handle::allocator): 623 (JSC::MarkedBlock::Handle::heap): 624 (JSC::MarkedBlock::Handle::vm): 625 (JSC::MarkedBlock::vm): 626 (JSC::MarkedBlock::Handle::weakSet): 627 (JSC::MarkedBlock::weakSet): 628 (JSC::MarkedBlock::Handle::shrink): 629 (JSC::MarkedBlock::Handle::visitWeakSet): 630 (JSC::MarkedBlock::Handle::reapWeakSet): 631 (JSC::MarkedBlock::Handle::cellSize): 632 (JSC::MarkedBlock::cellSize): 633 (JSC::MarkedBlock::Handle::attributes): 634 (JSC::MarkedBlock::attributes): 635 (JSC::MarkedBlock::Handle::needsDestruction): 636 (JSC::MarkedBlock::Handle::destruction): 637 (JSC::MarkedBlock::Handle::cellKind): 638 (JSC::MarkedBlock::Handle::markCount): 639 (JSC::MarkedBlock::Handle::size): 640 (JSC::MarkedBlock::atomNumber): 641 (JSC::MarkedBlock::flipIfNecessary): 642 (JSC::MarkedBlock::flipIfNecessaryConcurrently): 643 (JSC::MarkedBlock::Handle::flipIfNecessary): 644 (JSC::MarkedBlock::Handle::flipIfNecessaryConcurrently): 645 (JSC::MarkedBlock::Handle::flipForEdenCollection): 646 (JSC::MarkedBlock::assertFlipped): 647 (JSC::MarkedBlock::Handle::assertFlipped): 648 (JSC::MarkedBlock::isMarked): 649 (JSC::MarkedBlock::testAndSetMarked): 650 (JSC::MarkedBlock::Handle::isNewlyAllocated): 651 (JSC::MarkedBlock::Handle::setNewlyAllocated): 652 (JSC::MarkedBlock::Handle::clearNewlyAllocated): 653 (JSC::MarkedBlock::Handle::isMarkedOrNewlyAllocated): 654 (JSC::MarkedBlock::isMarkedOrNewlyAllocated): 655 (JSC::MarkedBlock::Handle::isLive): 656 (JSC::MarkedBlock::isAtom): 657 (JSC::MarkedBlock::Handle::isLiveCell): 658 (JSC::MarkedBlock::Handle::forEachCell): 659 (JSC::MarkedBlock::Handle::forEachLiveCell): 660 (JSC::MarkedBlock::Handle::forEachDeadCell): 661 (JSC::MarkedBlock::Handle::needsSweeping): 662 (JSC::MarkedBlock::Handle::isAllocated): 663 (JSC::MarkedBlock::Handle::isMarked): 664 (JSC::MarkedBlock::Handle::isFreeListed): 665 (JSC::MarkedBlock::hasAnyMarked): 666 (JSC::MarkedBlock::noteMarked): 667 (WTF::MarkedBlockHash::hash): 668 (JSC::MarkedBlock::FreeList::FreeList): Deleted. 669 (JSC::MarkedBlock::allocator): Deleted. 670 (JSC::MarkedBlock::heap): Deleted. 671 (JSC::MarkedBlock::shrink): Deleted. 672 (JSC::MarkedBlock::visitWeakSet): Deleted. 673 (JSC::MarkedBlock::reapWeakSet): Deleted. 674 (JSC::MarkedBlock::willRemoveBlock): Deleted. 675 (JSC::MarkedBlock::didConsumeFreeList): Deleted. 676 (JSC::MarkedBlock::markCount): Deleted. 677 (JSC::MarkedBlock::isEmpty): Deleted. 678 (JSC::MarkedBlock::destruction): Deleted. 679 (JSC::MarkedBlock::cellKind): Deleted. 680 (JSC::MarkedBlock::size): Deleted. 681 (JSC::MarkedBlock::capacity): Deleted. 682 (JSC::MarkedBlock::setMarked): Deleted. 683 (JSC::MarkedBlock::clearMarked): Deleted. 684 (JSC::MarkedBlock::isNewlyAllocated): Deleted. 685 (JSC::MarkedBlock::setNewlyAllocated): Deleted. 686 (JSC::MarkedBlock::clearNewlyAllocated): Deleted. 687 (JSC::MarkedBlock::isLive): Deleted. 688 (JSC::MarkedBlock::isLiveCell): Deleted. 689 (JSC::MarkedBlock::forEachCell): Deleted. 690 (JSC::MarkedBlock::forEachLiveCell): Deleted. 691 (JSC::MarkedBlock::forEachDeadCell): Deleted. 692 (JSC::MarkedBlock::needsSweeping): Deleted. 693 (JSC::MarkedBlock::isAllocated): Deleted. 694 (JSC::MarkedBlock::isMarkedOrRetired): Deleted. 695 * heap/MarkedSpace.cpp: 696 (JSC::MarkedSpace::initializeSizeClassForStepSize): 697 (JSC::MarkedSpace::MarkedSpace): 698 (JSC::MarkedSpace::~MarkedSpace): 699 (JSC::MarkedSpace::lastChanceToFinalize): 700 (JSC::MarkedSpace::allocate): 701 (JSC::MarkedSpace::tryAllocate): 702 (JSC::MarkedSpace::allocateLarge): 703 (JSC::MarkedSpace::tryAllocateLarge): 704 (JSC::MarkedSpace::sweep): 705 (JSC::MarkedSpace::sweepLargeAllocations): 706 (JSC::MarkedSpace::zombifySweep): 707 (JSC::MarkedSpace::resetAllocators): 708 (JSC::MarkedSpace::visitWeakSets): 709 (JSC::MarkedSpace::reapWeakSets): 710 (JSC::MarkedSpace::stopAllocating): 711 (JSC::MarkedSpace::prepareForMarking): 712 (JSC::MarkedSpace::resumeAllocating): 713 (JSC::MarkedSpace::isPagedOut): 714 (JSC::MarkedSpace::freeBlock): 715 (JSC::MarkedSpace::freeOrShrinkBlock): 716 (JSC::MarkedSpace::shrink): 717 (JSC::MarkedSpace::clearNewlyAllocated): 718 (JSC::VerifyMarked::operator()): 719 (JSC::MarkedSpace::flip): 720 (JSC::MarkedSpace::objectCount): 721 (JSC::MarkedSpace::size): 722 (JSC::MarkedSpace::capacity): 723 (JSC::MarkedSpace::addActiveWeakSet): 724 (JSC::MarkedSpace::didAddBlock): 725 (JSC::MarkedSpace::didAllocateInBlock): 726 (JSC::MarkedSpace::forEachAllocator): Deleted. 727 (JSC::VerifyMarkedOrRetired::operator()): Deleted. 728 (JSC::MarkedSpace::clearMarks): Deleted. 729 * heap/MarkedSpace.h: 730 (JSC::MarkedSpace::sizeClassToIndex): 731 (JSC::MarkedSpace::indexToSizeClass): 732 (JSC::MarkedSpace::version): 733 (JSC::MarkedSpace::blocksWithNewObjects): 734 (JSC::MarkedSpace::largeAllocations): 735 (JSC::MarkedSpace::largeAllocationsNurseryOffset): 736 (JSC::MarkedSpace::largeAllocationsOffsetForThisCollection): 737 (JSC::MarkedSpace::largeAllocationsForThisCollectionBegin): 738 (JSC::MarkedSpace::largeAllocationsForThisCollectionEnd): 739 (JSC::MarkedSpace::largeAllocationsForThisCollectionSize): 740 (JSC::MarkedSpace::forEachLiveCell): 741 (JSC::MarkedSpace::forEachDeadCell): 742 (JSC::MarkedSpace::allocatorFor): 743 (JSC::MarkedSpace::destructorAllocatorFor): 744 (JSC::MarkedSpace::auxiliaryAllocatorFor): 745 (JSC::MarkedSpace::allocateWithoutDestructor): 746 (JSC::MarkedSpace::allocateWithDestructor): 747 (JSC::MarkedSpace::allocateAuxiliary): 748 (JSC::MarkedSpace::tryAllocateAuxiliary): 749 (JSC::MarkedSpace::forEachBlock): 750 (JSC::MarkedSpace::forEachAllocator): 751 (JSC::MarkedSpace::optimalSizeFor): 752 (JSC::MarkedSpace::didAddBlock): Deleted. 753 (JSC::MarkedSpace::didAllocateInBlock): Deleted. 754 (JSC::MarkedSpace::objectCount): Deleted. 755 (JSC::MarkedSpace::size): Deleted. 756 (JSC::MarkedSpace::capacity): Deleted. 757 * heap/SlotVisitor.cpp: 758 (JSC::SlotVisitor::SlotVisitor): 759 (JSC::SlotVisitor::didStartMarking): 760 (JSC::SlotVisitor::reset): 761 (JSC::SlotVisitor::append): 762 (JSC::SlotVisitor::appendJSCellOrAuxiliary): 763 (JSC::SlotVisitor::setMarkedAndAppendToMarkStack): 764 (JSC::SlotVisitor::appendToMarkStack): 765 (JSC::SlotVisitor::markAuxiliary): 766 (JSC::SlotVisitor::noteLiveAuxiliaryCell): 767 (JSC::SlotVisitor::visitChildren): 768 * heap/SlotVisitor.h: 769 * heap/WeakBlock.cpp: 770 (JSC::WeakBlock::create): 771 (JSC::WeakBlock::WeakBlock): 772 (JSC::WeakBlock::visit): 773 (JSC::WeakBlock::reap): 774 * heap/WeakBlock.h: 775 (JSC::WeakBlock::disconnectContainer): 776 (JSC::WeakBlock::disconnectMarkedBlock): Deleted. 777 * heap/WeakSet.cpp: 778 (JSC::WeakSet::~WeakSet): 779 (JSC::WeakSet::sweep): 780 (JSC::WeakSet::shrink): 781 (JSC::WeakSet::addAllocator): 782 * heap/WeakSet.h: 783 (JSC::WeakSet::container): 784 (JSC::WeakSet::setContainer): 785 (JSC::WeakSet::WeakSet): 786 (JSC::WeakSet::visit): 787 (JSC::WeakSet::shrink): Deleted. 788 * heap/WeakSetInlines.h: 789 (JSC::WeakSet::allocate): 790 * inspector/InjectedScriptManager.cpp: 791 * inspector/JSGlobalObjectInspectorController.cpp: 792 * inspector/JSJavaScriptCallFrame.cpp: 793 * inspector/ScriptDebugServer.cpp: 794 * inspector/agents/InspectorDebuggerAgent.cpp: 795 * interpreter/CachedCall.h: 796 (JSC::CachedCall::CachedCall): 797 * interpreter/Interpreter.cpp: 798 (JSC::loadVarargs): 799 (JSC::StackFrame::sourceID): Deleted. 800 (JSC::StackFrame::sourceURL): Deleted. 801 (JSC::StackFrame::functionName): Deleted. 802 (JSC::StackFrame::computeLineAndColumn): Deleted. 803 (JSC::StackFrame::toString): Deleted. 804 * interpreter/Interpreter.h: 805 (JSC::StackFrame::isNative): Deleted. 806 * jit/AssemblyHelpers.h: 807 (JSC::AssemblyHelpers::emitAllocateWithNonNullAllocator): 808 (JSC::AssemblyHelpers::emitAllocate): 809 (JSC::AssemblyHelpers::emitAllocateJSCell): 810 (JSC::AssemblyHelpers::emitAllocateJSObject): 811 (JSC::AssemblyHelpers::emitAllocateJSObjectWithKnownSize): 812 (JSC::AssemblyHelpers::emitAllocateVariableSized): 813 * jit/GCAwareJITStubRoutine.cpp: 814 (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine): 815 * jit/JIT.cpp: 816 (JSC::JIT::compileCTINativeCall): 817 (JSC::JIT::link): 818 * jit/JIT.h: 819 (JSC::JIT::compileCTINativeCall): Deleted. 820 * jit/JITExceptions.cpp: 821 (JSC::genericUnwind): 822 * jit/JITExceptions.h: 823 * jit/JITOpcodes.cpp: 824 (JSC::JIT::emit_op_new_object): 825 (JSC::JIT::emitSlow_op_new_object): 826 (JSC::JIT::emit_op_create_this): 827 (JSC::JIT::emitSlow_op_create_this): 828 * jit/JITOpcodes32_64.cpp: 829 (JSC::JIT::emit_op_new_object): 830 (JSC::JIT::emitSlow_op_new_object): 831 (JSC::JIT::emit_op_create_this): 832 (JSC::JIT::emitSlow_op_create_this): 833 * jit/JITOperations.cpp: 834 * jit/JITOperations.h: 835 * jit/JITPropertyAccess.cpp: 836 (JSC::JIT::emitWriteBarrier): 837 * jit/JITThunks.cpp: 838 * jit/JITThunks.h: 839 * jsc.cpp: 840 (functionDescribeArray): 841 (main): 842 * llint/LLIntData.cpp: 843 (JSC::LLInt::Data::performAssertions): 844 * llint/LLIntExceptions.cpp: 845 * llint/LLIntThunks.cpp: 846 * llint/LLIntThunks.h: 847 * llint/LowLevelInterpreter.asm: 848 * llint/LowLevelInterpreter.cpp: 849 * llint/LowLevelInterpreter32_64.asm: 850 * llint/LowLevelInterpreter64.asm: 851 * parser/ModuleAnalyzer.cpp: 852 * parser/NodeConstructors.h: 853 * parser/Nodes.h: 854 * profiler/ProfilerBytecode.cpp: 855 * profiler/ProfilerBytecode.h: 856 * profiler/ProfilerBytecodeSequence.cpp: 857 * runtime/ArrayConventions.h: 858 (JSC::indexingHeaderForArrayStorage): 859 (JSC::baseIndexingHeaderForArrayStorage): 860 (JSC::indexingHeaderForArray): Deleted. 861 (JSC::baseIndexingHeaderForArray): Deleted. 862 * runtime/ArrayPrototype.cpp: 863 (JSC::arrayProtoFuncSplice): 864 (JSC::concatAppendOne): 865 (JSC::arrayProtoPrivateFuncConcatMemcpy): 866 * runtime/ArrayStorage.h: 867 (JSC::ArrayStorage::vectorLength): 868 (JSC::ArrayStorage::totalSizeFor): 869 (JSC::ArrayStorage::totalSize): 870 (JSC::ArrayStorage::availableVectorLength): 871 (JSC::ArrayStorage::optimalVectorLength): 872 (JSC::ArrayStorage::sizeFor): Deleted. 873 * runtime/AuxiliaryBarrier.h: Added. 874 (JSC::AuxiliaryBarrier::AuxiliaryBarrier): 875 (JSC::AuxiliaryBarrier::clear): 876 (JSC::AuxiliaryBarrier::get): 877 (JSC::AuxiliaryBarrier::slot): 878 (JSC::AuxiliaryBarrier::operator bool): 879 (JSC::AuxiliaryBarrier::setWithoutBarrier): 880 * runtime/AuxiliaryBarrierInlines.h: Added. 881 (JSC::AuxiliaryBarrier<T>::AuxiliaryBarrier): 882 (JSC::AuxiliaryBarrier<T>::set): 883 * runtime/Butterfly.h: 884 * runtime/ButterflyInlines.h: 885 (JSC::Butterfly::availableContiguousVectorLength): 886 (JSC::Butterfly::optimalContiguousVectorLength): 887 (JSC::Butterfly::createUninitialized): 888 (JSC::Butterfly::growArrayRight): 889 * runtime/ClonedArguments.cpp: 890 (JSC::ClonedArguments::createEmpty): 891 * runtime/CommonSlowPathsExceptions.cpp: 892 * runtime/CommonSlowPathsExceptions.h: 893 * runtime/DataView.cpp: 894 * runtime/DirectArguments.h: 895 * runtime/ECMAScriptSpecInternalFunctions.cpp: 896 * runtime/Error.cpp: 897 * runtime/Error.h: 898 * runtime/ErrorInstance.cpp: 899 * runtime/ErrorInstance.h: 900 * runtime/Exception.cpp: 901 * runtime/Exception.h: 902 * runtime/GeneratorFrame.cpp: 903 * runtime/GeneratorPrototype.cpp: 904 * runtime/InternalFunction.cpp: 905 (JSC::InternalFunction::InternalFunction): 906 * runtime/IntlCollator.cpp: 907 * runtime/IntlCollatorConstructor.cpp: 908 * runtime/IntlCollatorPrototype.cpp: 909 * runtime/IntlDateTimeFormat.cpp: 910 * runtime/IntlDateTimeFormatConstructor.cpp: 911 * runtime/IntlDateTimeFormatPrototype.cpp: 912 * runtime/IntlNumberFormat.cpp: 913 * runtime/IntlNumberFormatConstructor.cpp: 914 * runtime/IntlNumberFormatPrototype.cpp: 915 * runtime/IntlObject.cpp: 916 * runtime/IteratorPrototype.cpp: 917 * runtime/JSArray.cpp: 918 (JSC::JSArray::tryCreateUninitialized): 919 (JSC::JSArray::setLengthWritable): 920 (JSC::JSArray::unshiftCountSlowCase): 921 (JSC::JSArray::setLengthWithArrayStorage): 922 (JSC::JSArray::appendMemcpy): 923 (JSC::JSArray::setLength): 924 (JSC::JSArray::pop): 925 (JSC::JSArray::push): 926 (JSC::JSArray::fastSlice): 927 (JSC::JSArray::shiftCountWithArrayStorage): 928 (JSC::JSArray::shiftCountWithAnyIndexingType): 929 (JSC::JSArray::unshiftCountWithArrayStorage): 930 (JSC::JSArray::fillArgList): 931 (JSC::JSArray::copyToArguments): 932 * runtime/JSArray.h: 933 (JSC::createContiguousArrayButterfly): 934 (JSC::createArrayButterfly): 935 (JSC::JSArray::create): 936 (JSC::JSArray::tryCreateUninitialized): Deleted. 937 * runtime/JSArrayBufferView.h: 938 * runtime/JSCInlines.h: 939 * runtime/JSCJSValue.cpp: 940 (JSC::JSValue::dumpInContextAssumingStructure): 941 * runtime/JSCallee.cpp: 942 (JSC::JSCallee::JSCallee): 943 * runtime/JSCell.cpp: 944 (JSC::JSCell::estimatedSize): 945 * runtime/JSCell.h: 946 (JSC::JSCell::cellStateOffset): Deleted. 947 * runtime/JSCellInlines.h: 948 (JSC::ExecState::vm): 949 (JSC::JSCell::classInfo): 950 (JSC::JSCell::callDestructor): 951 (JSC::JSCell::vm): Deleted. 952 * runtime/JSFunction.cpp: 953 (JSC::JSFunction::create): 954 (JSC::JSFunction::allocateAndInitializeRareData): 955 (JSC::JSFunction::initializeRareData): 956 (JSC::JSFunction::getOwnPropertySlot): 957 (JSC::JSFunction::put): 958 (JSC::JSFunction::deleteProperty): 959 (JSC::JSFunction::defineOwnProperty): 960 (JSC::JSFunction::setFunctionName): 961 (JSC::JSFunction::reifyLength): 962 (JSC::JSFunction::reifyName): 963 (JSC::JSFunction::reifyLazyPropertyIfNeeded): 964 (JSC::JSFunction::reifyBoundNameIfNeeded): 965 * runtime/JSFunction.h: 966 * runtime/JSFunctionInlines.h: 967 (JSC::JSFunction::createWithInvalidatedReallocationWatchpoint): 968 (JSC::JSFunction::JSFunction): 969 * runtime/JSGenericTypedArrayViewInlines.h: 970 (JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory): 971 * runtime/JSInternalPromise.cpp: 972 * runtime/JSInternalPromiseConstructor.cpp: 973 * runtime/JSInternalPromiseDeferred.cpp: 974 * runtime/JSInternalPromisePrototype.cpp: 975 * runtime/JSJob.cpp: 976 * runtime/JSMapIterator.cpp: 977 * runtime/JSModuleNamespaceObject.cpp: 978 * runtime/JSModuleRecord.cpp: 979 * runtime/JSObject.cpp: 980 (JSC::JSObject::visitButterfly): 981 (JSC::JSObject::notifyPresenceOfIndexedAccessors): 982 (JSC::JSObject::createInitialIndexedStorage): 983 (JSC::JSObject::createInitialUndecided): 984 (JSC::JSObject::createInitialInt32): 985 (JSC::JSObject::createInitialDouble): 986 (JSC::JSObject::createInitialContiguous): 987 (JSC::JSObject::createArrayStorage): 988 (JSC::JSObject::createInitialArrayStorage): 989 (JSC::JSObject::convertUndecidedToInt32): 990 (JSC::JSObject::convertUndecidedToContiguous): 991 (JSC::JSObject::convertUndecidedToArrayStorage): 992 (JSC::JSObject::convertInt32ToDouble): 993 (JSC::JSObject::convertInt32ToArrayStorage): 994 (JSC::JSObject::convertDoubleToArrayStorage): 995 (JSC::JSObject::convertContiguousToArrayStorage): 996 (JSC::JSObject::putByIndexBeyondVectorLength): 997 (JSC::JSObject::putDirectIndexBeyondVectorLength): 998 (JSC::JSObject::getNewVectorLength): 999 (JSC::JSObject::increaseVectorLength): 1000 (JSC::JSObject::ensureLengthSlow): 1001 (JSC::JSObject::growOutOfLineStorage): 1002 (JSC::JSObject::copyButterfly): Deleted. 1003 (JSC::JSObject::copyBackingStore): Deleted. 1004 * runtime/JSObject.h: 1005 (JSC::JSObject::globalObject): 1006 (JSC::JSObject::putDirectInternal): 1007 (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): Deleted. 1008 * runtime/JSObjectInlines.h: 1009 * runtime/JSPromise.cpp: 1010 * runtime/JSPromiseConstructor.cpp: 1011 * runtime/JSPromiseDeferred.cpp: 1012 * runtime/JSPromisePrototype.cpp: 1013 * runtime/JSPropertyNameIterator.cpp: 1014 * runtime/JSScope.cpp: 1015 (JSC::JSScope::resolve): 1016 * runtime/JSScope.h: 1017 (JSC::JSScope::globalObject): 1018 (JSC::JSScope::vm): Deleted. 1019 * runtime/JSSetIterator.cpp: 1020 * runtime/JSStringIterator.cpp: 1021 * runtime/JSTemplateRegistryKey.cpp: 1022 * runtime/JSTypedArrayViewConstructor.cpp: 1023 * runtime/JSTypedArrayViewPrototype.cpp: 1024 * runtime/JSWeakMap.cpp: 1025 * runtime/JSWeakSet.cpp: 1026 * runtime/MapConstructor.cpp: 1027 * runtime/MapIteratorPrototype.cpp: 1028 * runtime/MapPrototype.cpp: 1029 * runtime/NativeErrorConstructor.cpp: 1030 * runtime/NativeStdFunctionCell.cpp: 1031 * runtime/Operations.h: 1032 (JSC::scribbleFreeCells): 1033 (JSC::scribble): 1034 * runtime/Options.h: 1035 * runtime/PropertyTable.cpp: 1036 * runtime/ProxyConstructor.cpp: 1037 * runtime/ProxyObject.cpp: 1038 * runtime/ProxyRevoke.cpp: 1039 * runtime/RegExp.cpp: 1040 (JSC::RegExp::match): 1041 (JSC::RegExp::matchConcurrently): 1042 (JSC::RegExp::matchCompareWithInterpreter): 1043 * runtime/RegExp.h: 1044 * runtime/RegExpConstructor.h: 1045 * runtime/RegExpInlines.h: 1046 (JSC::RegExp::matchInline): 1047 * runtime/RegExpMatchesArray.h: 1048 (JSC::tryCreateUninitializedRegExpMatchesArray): 1049 (JSC::createRegExpMatchesArray): 1050 * runtime/RegExpPrototype.cpp: 1051 (JSC::genericSplit): 1052 * runtime/RuntimeType.cpp: 1053 * runtime/SamplingProfiler.cpp: 1054 (JSC::SamplingProfiler::processUnverifiedStackTraces): 1055 * runtime/SetConstructor.cpp: 1056 * runtime/SetIteratorPrototype.cpp: 1057 * runtime/SetPrototype.cpp: 1058 * runtime/StackFrame.cpp: Added. 1059 (JSC::StackFrame::sourceID): 1060 (JSC::StackFrame::sourceURL): 1061 (JSC::StackFrame::functionName): 1062 (JSC::StackFrame::computeLineAndColumn): 1063 (JSC::StackFrame::toString): 1064 * runtime/StackFrame.h: Added. 1065 (JSC::StackFrame::isNative): 1066 * runtime/StringConstructor.cpp: 1067 * runtime/StringIteratorPrototype.cpp: 1068 * runtime/StructureInlines.h: 1069 (JSC::Structure::propertyTable): 1070 * runtime/TemplateRegistry.cpp: 1071 * runtime/TestRunnerUtils.cpp: 1072 (JSC::finalizeStatsAtEndOfTesting): 1073 * runtime/TestRunnerUtils.h: 1074 * runtime/TypeProfilerLog.cpp: 1075 * runtime/TypeSet.cpp: 1076 * runtime/VM.cpp: 1077 (JSC::VM::VM): 1078 (JSC::VM::ensureStackCapacityForCLoop): 1079 (JSC::VM::isSafeToRecurseSoftCLoop): 1080 * runtime/VM.h: 1081 * runtime/VMEntryScope.h: 1082 * runtime/VMInlines.h: 1083 (JSC::VM::ensureStackCapacityFor): 1084 (JSC::VM::isSafeToRecurseSoft): 1085 * runtime/WeakMapConstructor.cpp: 1086 * runtime/WeakMapData.cpp: 1087 * runtime/WeakMapPrototype.cpp: 1088 * runtime/WeakSetConstructor.cpp: 1089 * runtime/WeakSetPrototype.cpp: 1090 * testRegExp.cpp: 1091 (testOneRegExp): 1092 * tools/JSDollarVM.cpp: 1093 * tools/JSDollarVMPrototype.cpp: 1094 (JSC::JSDollarVMPrototype::isInObjectSpace): 1095 1 1096 2016-09-04 Commit Queue <commit-queue@webkit.org> 2 1097 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r205330 r205462 89 89 0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F04396C1B03DC0B009598B7 /* DFGCombinedLiveness.h */; }; 90 90 0F05C3B41683CF9200BAF45B /* DFGArrayifySlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */; }; 91 0F070A471D543A8B006E7232 /* CellContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F070A421D543A89006E7232 /* CellContainer.h */; settings = {ATTRIBUTES = (Private, ); }; }; 92 0F070A481D543A90006E7232 /* CellContainerInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F070A431D543A89006E7232 /* CellContainerInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 93 0F070A491D543A93006E7232 /* HeapCellInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F070A441D543A89006E7232 /* HeapCellInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 94 0F070A4A1D543A95006E7232 /* LargeAllocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F070A451D543A89006E7232 /* LargeAllocation.cpp */; }; 95 0F070A4B1D543A98006E7232 /* LargeAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F070A461D543A89006E7232 /* LargeAllocation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 91 96 0F0776BF14FF002B00102332 /* JITCompilationEffort.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0776BD14FF002800102332 /* JITCompilationEffort.h */; settings = {ATTRIBUTES = (Private, ); }; }; 92 97 0F0A75221B94BFA900110660 /* InferredType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0A75201B94BFA900110660 /* InferredType.cpp */; }; … … 324 329 0F38B01917CFE75500B144D3 /* DFGCompilationMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B01517CFE75500B144D3 /* DFGCompilationMode.cpp */; }; 325 330 0F38B01A17CFE75500B144D3 /* DFGCompilationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 331 0F38D2A21D44196800680499 /* AuxiliaryBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38D2A01D44196600680499 /* AuxiliaryBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; }; 332 0F38D2A31D44196D00680499 /* AuxiliaryBarrierInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F38D2A11D44196600680499 /* AuxiliaryBarrierInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 326 333 0F392C891B46188400844728 /* DFGOSRExitFuzz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F392C871B46188400844728 /* DFGOSRExitFuzz.cpp */; }; 327 334 0F392C8A1B46188400844728 /* DFGOSRExitFuzz.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F392C881B46188400844728 /* DFGOSRExitFuzz.h */; }; … … 365 372 0F4680CB14BBB17200BFE272 /* LLIntOfflineAsmConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C614BBB16900BFE272 /* LLIntOfflineAsmConfig.h */; settings = {ATTRIBUTES = (Private, ); }; }; 366 373 0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680C714BBB16900BFE272 /* LowLevelInterpreter.cpp */; }; 367 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */; settings = {ATTRIBUTES = (Private, ); };};374 0F4680CD14BBB17D00BFE272 /* LowLevelInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680C814BBB16900BFE272 /* LowLevelInterpreter.h */; }; 368 375 0F4680D214BBD16500BFE272 /* LLIntData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680CE14BBB3D100BFE272 /* LLIntData.cpp */; }; 369 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680CF14BBB3D100BFE272 /* LLIntData.h */; settings = {ATTRIBUTES = (Private, ); };};376 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680CF14BBB3D100BFE272 /* LLIntData.h */; }; 370 377 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */; }; 371 378 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 387 394 0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; }; 388 395 0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; }; 396 0F5513A61D5A682C00C32BD8 /* FreeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5513A51D5A682A00C32BD8 /* FreeList.h */; settings = {ATTRIBUTES = (Private, ); }; }; 397 0F5513A81D5A68CD00C32BD8 /* FreeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5513A71D5A68CB00C32BD8 /* FreeList.cpp */; }; 389 398 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; }; 390 399 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 459 468 0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */; }; 460 469 0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */; settings = {ATTRIBUTES = (Private, ); }; }; 470 0F6DB7E91D6124B500CDBF8E /* StackFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6DB7E81D6124B200CDBF8E /* StackFrame.h */; settings = {ATTRIBUTES = (Private, ); }; }; 471 0F6DB7EA1D6124B800CDBF8E /* StackFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6DB7E71D6124B200CDBF8E /* StackFrame.cpp */; }; 472 0F6DB7EC1D617D1100CDBF8E /* MacroAssemblerCodeRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6DB7EB1D617D0F00CDBF8E /* MacroAssemblerCodeRef.cpp */; }; 461 473 0F6E845A19030BEF00562741 /* DFGVariableAccessData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */; }; 462 474 0F6FC750196110A800E1D02D /* ComplexGetStatus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */; }; … … 494 506 0F8335B81639C1EA001443B5 /* ArrayAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; }; 495 507 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */; }; 508 0F86A26D1D6F796500CB0C92 /* HeapOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F86A26C1D6F796200CB0C92 /* HeapOperation.cpp */; }; 509 0F86A26F1D6F7B3300CB0C92 /* GCTypeMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */; }; 496 510 0F86AE201C5311C5006BE8EC /* B3ComputeDivisionMagic.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F86AE1F1C5311C5006BE8EC /* B3ComputeDivisionMagic.h */; }; 497 511 0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 574 588 0FA7A8EC18B413C80052371D /* Reg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA7A8EA18B413C80052371D /* Reg.h */; settings = {ATTRIBUTES = (Private, ); }; }; 575 589 0FA7A8EE18CE4FD80052371D /* ScratchRegisterAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */; }; 590 0FADE6731D4D23BE00768457 /* HeapUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FADE6721D4D23BC00768457 /* HeapUtil.h */; }; 576 591 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */; }; 577 592 0FAF7EFE165BA91F000C8455 /* JITDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 594 609 0FB387901BFBC44D00E3AB1E /* AirOptimizeBlockOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB3878D1BFBC44D00E3AB1E /* AirOptimizeBlockOrder.h */; }; 595 610 0FB387921BFD31A100E3AB1E /* FTLCompile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB387911BFD31A100E3AB1E /* FTLCompile.cpp */; }; 611 0FB415841D78FB4C00DF8D09 /* ArrayConventions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB415831D78F98200DF8D09 /* ArrayConventions.cpp */; }; 596 612 0FB438A319270B1D00E1FBC9 /* StructureSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */; }; 597 613 0FB4FB731BC843140025CA5A /* FTLLazySlowPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FB4FB701BC843140025CA5A /* FTLLazySlowPath.cpp */; }; … … 990 1006 14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */; }; 991 1007 14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65EA4C99092AF9E20093D800 /* JSLock.cpp */; }; 992 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D77B0ED20D7300B89619 /* Interpreter.h */; settings = {ATTRIBUTES = (Private, ); };};1008 1429D77C0ED20D7300B89619 /* Interpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D77B0ED20D7300B89619 /* Interpreter.h */; }; 993 1009 1429D7D40ED2128200B89619 /* Interpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D7D30ED2128200B89619 /* Interpreter.cpp */; }; 994 1010 1429D8780ED21ACD00B89619 /* ExceptionHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */; }; … … 1450 1466 969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07930ED1D3AE00F1F681 /* Instruction.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1451 1467 969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07940ED1D3AE00F1F681 /* Opcode.cpp */; }; 1452 969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); };};1468 969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; }; 1453 1469 978801401471AD920041B016 /* JSDateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */; }; 1454 1470 978801411471AD920041B016 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 2314 2330 0F04396C1B03DC0B009598B7 /* DFGCombinedLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCombinedLiveness.h; path = dfg/DFGCombinedLiveness.h; sourceTree = "<group>"; }; 2315 2331 0F05C3B21683CF8F00BAF45B /* DFGArrayifySlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArrayifySlowPathGenerator.h; path = dfg/DFGArrayifySlowPathGenerator.h; sourceTree = "<group>"; }; 2332 0F070A421D543A89006E7232 /* CellContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CellContainer.h; sourceTree = "<group>"; }; 2333 0F070A431D543A89006E7232 /* CellContainerInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CellContainerInlines.h; sourceTree = "<group>"; }; 2334 0F070A441D543A89006E7232 /* HeapCellInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapCellInlines.h; sourceTree = "<group>"; }; 2335 0F070A451D543A89006E7232 /* LargeAllocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LargeAllocation.cpp; sourceTree = "<group>"; }; 2336 0F070A461D543A89006E7232 /* LargeAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LargeAllocation.h; sourceTree = "<group>"; }; 2316 2337 0F0776BD14FF002800102332 /* JITCompilationEffort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCompilationEffort.h; sourceTree = "<group>"; }; 2317 2338 0F0A75201B94BFA900110660 /* InferredType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InferredType.cpp; sourceTree = "<group>"; }; … … 2548 2569 0F38B01517CFE75500B144D3 /* DFGCompilationMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGCompilationMode.cpp; path = dfg/DFGCompilationMode.cpp; sourceTree = "<group>"; }; 2549 2570 0F38B01617CFE75500B144D3 /* DFGCompilationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCompilationMode.h; path = dfg/DFGCompilationMode.h; sourceTree = "<group>"; }; 2571 0F38D2A01D44196600680499 /* AuxiliaryBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuxiliaryBarrier.h; sourceTree = "<group>"; }; 2572 0F38D2A11D44196600680499 /* AuxiliaryBarrierInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuxiliaryBarrierInlines.h; sourceTree = "<group>"; }; 2550 2573 0F392C871B46188400844728 /* DFGOSRExitFuzz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExitFuzz.cpp; path = dfg/DFGOSRExitFuzz.cpp; sourceTree = "<group>"; }; 2551 2574 0F392C881B46188400844728 /* DFGOSRExitFuzz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitFuzz.h; path = dfg/DFGOSRExitFuzz.h; sourceTree = "<group>"; }; … … 2609 2632 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = "<group>"; }; 2610 2633 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = "<group>"; }; 2634 0F5513A51D5A682A00C32BD8 /* FreeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FreeList.h; sourceTree = "<group>"; }; 2635 0F5513A71D5A68CB00C32BD8 /* FreeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FreeList.cpp; sourceTree = "<group>"; }; 2611 2636 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = "<group>"; }; 2612 2637 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialPointer.h; sourceTree = "<group>"; }; … … 2683 2708 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWriteFireDetail.cpp; sourceTree = "<group>"; }; 2684 2709 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWriteFireDetail.h; sourceTree = "<group>"; }; 2710 0F6DB7E71D6124B200CDBF8E /* StackFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackFrame.cpp; sourceTree = "<group>"; }; 2711 0F6DB7E81D6124B200CDBF8E /* StackFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackFrame.h; sourceTree = "<group>"; }; 2712 0F6DB7EB1D617D0F00CDBF8E /* MacroAssemblerCodeRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerCodeRef.cpp; sourceTree = "<group>"; }; 2685 2713 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessData.cpp; path = dfg/DFGVariableAccessData.cpp; sourceTree = "<group>"; }; 2686 2714 0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexGetStatus.cpp; sourceTree = "<group>"; }; … … 2716 2744 0F8335B51639C1E3001443B5 /* ArrayAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayAllocationProfile.h; sourceTree = "<group>"; }; 2717 2745 0F8364B5164B0C0E0053329A /* DFGBranchDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBranchDirection.h; path = dfg/DFGBranchDirection.h; sourceTree = "<group>"; }; 2746 0F86A26C1D6F796200CB0C92 /* HeapOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapOperation.cpp; sourceTree = "<group>"; }; 2747 0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCTypeMap.h; sourceTree = "<group>"; }; 2718 2748 0F86AE1F1C5311C5006BE8EC /* B3ComputeDivisionMagic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ComputeDivisionMagic.h; path = b3/B3ComputeDivisionMagic.h; sourceTree = "<group>"; }; 2719 2749 0F885E101849A3BE00F1E3FA /* BytecodeUseDef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeUseDef.h; sourceTree = "<group>"; }; … … 2795 2825 0FA7A8EA18B413C80052371D /* Reg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reg.h; sourceTree = "<group>"; }; 2796 2826 0FA7A8ED18CE4FD80052371D /* ScratchRegisterAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScratchRegisterAllocator.cpp; sourceTree = "<group>"; }; 2827 0FADE6721D4D23BC00768457 /* HeapUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapUtil.h; sourceTree = "<group>"; }; 2797 2828 0FAF7EFA165BA919000C8455 /* JITDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITDisassembler.cpp; sourceTree = "<group>"; }; 2798 2829 0FAF7EFB165BA919000C8455 /* JITDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITDisassembler.h; sourceTree = "<group>"; }; … … 2815 2846 0FB3878D1BFBC44D00E3AB1E /* AirOptimizeBlockOrder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirOptimizeBlockOrder.h; path = b3/air/AirOptimizeBlockOrder.h; sourceTree = "<group>"; }; 2816 2847 0FB387911BFD31A100E3AB1E /* FTLCompile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLCompile.cpp; path = ftl/FTLCompile.cpp; sourceTree = "<group>"; }; 2848 0FB415831D78F98200DF8D09 /* ArrayConventions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayConventions.cpp; sourceTree = "<group>"; }; 2817 2849 0FB438A219270B1D00E1FBC9 /* StructureSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureSet.cpp; sourceTree = "<group>"; }; 2818 2850 0FB4B51016B3A964003F696B /* DFGMinifiedID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGMinifiedID.h; path = dfg/DFGMinifiedID.h; sourceTree = "<group>"; }; … … 5240 5272 0F9630351D4192C3005609D9 /* AllocatorAttributes.cpp */, 5241 5273 0F9630361D4192C3005609D9 /* AllocatorAttributes.h */, 5274 0F070A421D543A89006E7232 /* CellContainer.h */, 5275 0F070A431D543A89006E7232 /* CellContainerInlines.h */, 5242 5276 0F1C3DD91BBCE09E00E523E4 /* CellState.h */, 5243 5277 0FD8A31117D4326C00CA2C40 /* CodeBlockSet.cpp */, … … 5264 5298 2A83638318D7D0EE0000EBCC /* EdenGCActivityCallback.cpp */, 5265 5299 2A83638418D7D0EE0000EBCC /* EdenGCActivityCallback.h */, 5300 0F5513A71D5A68CB00C32BD8 /* FreeList.cpp */, 5301 0F5513A51D5A682A00C32BD8 /* FreeList.h */, 5266 5302 2A83638718D7D0FE0000EBCC /* FullGCActivityCallback.cpp */, 5267 5303 2A83638818D7D0FE0000EBCC /* FullGCActivityCallback.h */, … … 5277 5313 2A343F7418A1748B0039B085 /* GCSegmentedArray.h */, 5278 5314 2A343F7718A1749D0039B085 /* GCSegmentedArrayInlines.h */, 5315 0F86A26E1D6F7B3100CB0C92 /* GCTypeMap.h */, 5279 5316 142E312B134FF0A600AFADB5 /* Handle.h */, 5280 5317 C28318FF16FE4B7D00157BFD /* HandleBlock.h */, … … 5289 5326 DC3D2B0B1D34376E00BA918C /* HeapCell.cpp */, 5290 5327 DC3D2B091D34316100BA918C /* HeapCell.h */, 5328 0F070A441D543A89006E7232 /* HeapCellInlines.h */, 5291 5329 0F32BD0E1BB34F190093A57F /* HeapHelperPool.cpp */, 5292 5330 0F32BD0F1BB34F190093A57F /* HeapHelperPool.h */, … … 5294 5332 2AD8932917E3868F00668276 /* HeapIterationScope.h */, 5295 5333 A5339EC81BB4B4510054F005 /* HeapObserver.h */, 5334 0F86A26C1D6F796200CB0C92 /* HeapOperation.cpp */, 5296 5335 2A6F462517E959CE00C45C98 /* HeapOperation.h */, 5297 5336 A5398FA91C750D950060A963 /* HeapProfiler.cpp */, … … 5306 5345 C2E526BB1590EF000054E48D /* HeapTimer.cpp */, 5307 5346 C2E526BC1590EF000054E48D /* HeapTimer.h */, 5347 0FADE6721D4D23BC00768457 /* HeapUtil.h */, 5308 5348 FE7BA60D1A1A7CEC00F1F7B4 /* HeapVerifier.cpp */, 5309 5349 FE7BA60E1A1A7CEC00F1F7B4 /* HeapVerifier.h */, … … 5312 5352 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */, 5313 5353 0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */, 5354 0F070A451D543A89006E7232 /* LargeAllocation.cpp */, 5355 0F070A461D543A89006E7232 /* LargeAllocation.h */, 5314 5356 0F431736146BAC65007E3890 /* ListableHandler.h */, 5315 5357 FE3913511B794AC900EDAF71 /* LiveObjectData.h */, … … 5663 5705 BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */, 5664 5706 BC7952070E15E8A800A898AB /* ArrayConstructor.h */, 5707 0FB415831D78F98200DF8D09 /* ArrayConventions.cpp */, 5665 5708 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */, 5666 5709 A7BDAEC217F4EA1400F6140C /* ArrayIteratorPrototype.cpp */, … … 5669 5712 F692A84E0255597D01FF60F7 /* ArrayPrototype.h */, 5670 5713 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */, 5714 0F38D2A01D44196600680499 /* AuxiliaryBarrier.h */, 5715 0F38D2A11D44196600680499 /* AuxiliaryBarrierInlines.h */, 5671 5716 52678F8C1A031009006A306D /* BasicBlockLocation.cpp */, 5672 5717 52678F8D1A031009006A306D /* BasicBlockLocation.h */, … … 5833 5878 93ADFCE60CCBD7AC00D30B08 /* JSArray.cpp */, 5834 5879 938772E5038BFE19008635CE /* JSArray.h */, 5835 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */,5836 5880 0F2B66B417B6B5AB00A7AE3F /* JSArrayBuffer.cpp */, 5837 5881 0F2B66B517B6B5AB00A7AE3F /* JSArrayBuffer.h */, … … 5843 5887 0F2B66BB17B6B5AB00A7AE3F /* JSArrayBufferView.h */, 5844 5888 0F2B66BC17B6B5AB00A7AE3F /* JSArrayBufferViewInlines.h */, 5889 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */, 5845 5890 86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */, 5846 5891 86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */, … … 5911 5956 E3D239C61B829C1C00BBEF67 /* JSModuleEnvironment.cpp */, 5912 5957 E3D239C71B829C1C00BBEF67 /* JSModuleEnvironment.h */, 5958 1879510614C540FFB561C124 /* JSModuleLoader.cpp */, 5959 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */, 5913 5960 E318CBBE1B8AEF5100A2929D /* JSModuleNamespaceObject.cpp */, 5914 5961 E318CBBF1B8AEF5100A2929D /* JSModuleNamespaceObject.h */, … … 6103 6150 0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */, 6104 6151 0F3AC751183EA1040032029F /* StackAlignment.h */, 6152 0F6DB7E71D6124B200CDBF8E /* StackFrame.cpp */, 6153 0F6DB7E81D6124B200CDBF8E /* StackFrame.h */, 6105 6154 A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */, 6106 6155 A730B6101250068F009D25B1 /* StrictEvalActivation.h */, … … 6191 6240 A7DCB77912E3D90500911940 /* WriteBarrier.h */, 6192 6241 C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */, 6193 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */,6194 1879510614C540FFB561C124 /* JSModuleLoader.cpp */,6195 6242 ); 6196 6243 path = runtime; … … 6635 6682 A729009B17976C6000317298 /* MacroAssemblerARMv7.cpp */, 6636 6683 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */, 6684 0F6DB7EB1D617D0F00CDBF8E /* MacroAssemblerCodeRef.cpp */, 6637 6685 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */, 6638 6686 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */, … … 7246 7294 0F338E111BF0276C0013C88F /* B3OpaqueByproduct.h in Headers */, 7247 7295 FEA0C4031CDD7D1D00481991 /* FunctionWhitelist.h in Headers */, 7296 0F6DB7E91D6124B500CDBF8E /* StackFrame.h in Headers */, 7248 7297 E3A421431D6F58930007C617 /* PreciseJumpTargetsInlines.h in Headers */, 7249 7298 99DA00AA1BD5993100F4575C /* builtins_generate_separate_implementation.py in Headers */, … … 7338 7387 0F9495881C57F47500413A48 /* B3StackSlot.h in Headers */, 7339 7388 C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */, 7389 0F38D2A21D44196800680499 /* AuxiliaryBarrier.h in Headers */, 7340 7390 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */, 7341 7391 9959E92B1BD17FA4001AA413 /* cssmin.py in Headers */, … … 7467 7517 99D6A1161BEAD34D00E25C37 /* RemoteAutomationTarget.h in Headers */, 7468 7518 79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */, 7519 0F86A26F1D6F7B3300CB0C92 /* GCTypeMap.h in Headers */, 7469 7520 A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */, 7470 7521 0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */, … … 7563 7614 0FC97F4218202119002C9B26 /* DFGWatchpointCollectionPhase.h in Headers */, 7564 7615 0FDB2CE8174830A2007B3C1B /* DFGWorklist.h in Headers */, 7616 0F070A491D543A93006E7232 /* HeapCellInlines.h in Headers */, 7565 7617 0FE050181AA9091100D33B33 /* DirectArguments.h in Headers */, 7566 7618 0FE050161AA9091100D33B33 /* DirectArgumentsOffset.h in Headers */, … … 7693 7745 FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */, 7694 7746 708EBE241CE8F35800453146 /* IntlObjectInlines.h in Headers */, 7747 0F070A481D543A90006E7232 /* CellContainerInlines.h in Headers */, 7695 7748 FE6029D91D6E1E4F0030204D /* ThrowScopeLocation.h in Headers */, 7696 7749 0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */, … … 7780 7833 FE187A0F1C030D6C0038BBCA /* SnippetOperand.h in Headers */, 7781 7834 A1587D701B4DC14100D69849 /* IntlDateTimeFormatConstructor.h in Headers */, 7835 0FADE6731D4D23BE00768457 /* HeapUtil.h in Headers */, 7782 7836 A1587D751B4DC1C600D69849 /* IntlDateTimeFormatConstructor.lut.h in Headers */, 7783 7837 A5398FAB1C750DA40060A963 /* HeapProfiler.h in Headers */, … … 7904 7958 2A4BB7F318A41179008A0FCD /* JSManagedValueInternal.h in Headers */, 7905 7959 A700874217CBE8EB00C3E643 /* JSMap.h in Headers */, 7960 0F38D2A31D44196D00680499 /* AuxiliaryBarrierInlines.h in Headers */, 7906 7961 A74DEF96182D991400522C22 /* JSMapIterator.h in Headers */, 7907 7962 9959E92D1BD17FA4001AA413 /* jsmin.py in Headers */, … … 7941 7996 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */, 7942 7997 70EC0EC31AA0D7DA00B6AAFA /* JSStringIterator.h in Headers */, 7998 0F070A471D543A8B006E7232 /* CellContainer.h in Headers */, 7943 7999 2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */, 7944 8000 BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */, … … 8011 8067 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */, 8012 8068 43422A671C16267800E2EB98 /* B3ReduceDoubleToFloat.h in Headers */, 8069 0F070A4B1D543A98006E7232 /* LargeAllocation.h in Headers */, 8013 8070 86D3B2C610156BDE002865E7 /* MacroAssemblerARM.h in Headers */, 8014 8071 A1A009C01831A22D00CF8711 /* MacroAssemblerARM64.h in Headers */, … … 8058 8115 996B73211BDA08EF00331B84 /* NumberPrototype.lut.h in Headers */, 8059 8116 142D3939103E4560007DCB52 /* NumericStrings.h in Headers */, 8117 0F5513A61D5A682C00C32BD8 /* FreeList.h in Headers */, 8060 8118 A5EA710C19F6DE820098F5EC /* objc_generator.py in Headers */, 8061 8119 C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */, … … 8840 8898 0F4DE1CE1C4C1B54004D6C11 /* AirFixObviousSpills.cpp in Sources */, 8841 8899 0FEC85711BDACDC70080FF74 /* AirBasicBlock.cpp in Sources */, 8900 0F070A4A1D543A95006E7232 /* LargeAllocation.cpp in Sources */, 8842 8901 0FEC85731BDACDC70080FF74 /* AirCCallSpecial.cpp in Sources */, 8843 8902 0FEC85751BDACDC70080FF74 /* AirCode.cpp in Sources */, … … 9101 9160 0FBE0F7416C1DB090082C5E8 /* DFGPredictionInjectionPhase.cpp in Sources */, 9102 9161 0FFFC95D14EF90B300C72532 /* DFGPredictionPropagationPhase.cpp in Sources */, 9162 0F86A26D1D6F796500CB0C92 /* HeapOperation.cpp in Sources */, 9103 9163 0F3E01AA19D353A500F61B7F /* DFGPrePostNumbering.cpp in Sources */, 9104 9164 0F2B9CEC19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.cpp in Sources */, … … 9262 9322 A1B9E2391B4E0D6700BC7FED /* IntlCollator.cpp in Sources */, 9263 9323 A1B9E23B1B4E0D6700BC7FED /* IntlCollatorConstructor.cpp in Sources */, 9324 0F6DB7EA1D6124B800CDBF8E /* StackFrame.cpp in Sources */, 9264 9325 A1B9E23D1B4E0D6700BC7FED /* IntlCollatorPrototype.cpp in Sources */, 9265 9326 A1587D6D1B4DC14100D69849 /* IntlDateTimeFormat.cpp in Sources */, … … 9285 9346 0F8F94441667635400D61971 /* JITCode.cpp in Sources */, 9286 9347 0FAF7EFD165BA91B000C8455 /* JITDisassembler.cpp in Sources */, 9348 0F6DB7EC1D617D1100CDBF8E /* MacroAssemblerCodeRef.cpp in Sources */, 9287 9349 0F46808314BA573100BFE272 /* JITExceptions.cpp in Sources */, 9288 9350 0FB14E1E18124ACE009B6B4D /* JITInlineCacheGenerator.cpp in Sources */, … … 9290 9352 A71236E51195F33C00BD2174 /* JITOpcodes32_64.cpp in Sources */, 9291 9353 0F24E54C17EE274900ABB217 /* JITOperations.cpp in Sources */, 9354 0F5513A81D5A68CD00C32BD8 /* FreeList.cpp in Sources */, 9292 9355 FE99B24A1C24C3D700C82159 /* JITNegGenerator.cpp in Sources */, 9293 9356 86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */, 9294 9357 A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */, 9358 0FB415841D78FB4C00DF8D09 /* ArrayConventions.cpp in Sources */, 9295 9359 0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */, 9296 9360 0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */, -
trunk/Source/JavaScriptCore/Scripts/builtins/builtins_generate_combined_implementation.py
r204912 r205462 73 73 ), 74 74 (["JavaScriptCore", "WebCore"], 75 ("JavaScriptCore", "heap/HeapInlines.h"), 76 ), 77 (["JavaScriptCore", "WebCore"], 75 78 ("JavaScriptCore", "runtime/Executable.h"), 76 79 ), -
trunk/Source/JavaScriptCore/Scripts/builtins/builtins_generate_internals_wrapper_implementation.py
r204912 r205462 67 67 (["WebCore"], 68 68 ("WebCore", "WebCoreJSClientData.h"), 69 ), 70 (["WebCore"], 71 ("JavaScriptCore", "heap/HeapInlines.h"), 69 72 ), 70 73 (["WebCore"], -
trunk/Source/JavaScriptCore/Scripts/builtins/builtins_generate_separate_implementation.py
r204912 r205462 85 85 ), 86 86 (["JavaScriptCore", "WebCore"], 87 ("JavaScriptCore", "heap/HeapInlines.h"), 88 ), 89 (["JavaScriptCore", "WebCore"], 87 90 ("JavaScriptCore", "runtime/Executable.h"), 88 91 ), -
trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
r204912 r205462 726 726 } 727 727 728 void link(AbstractMacroAssemblerType* masm) 728 void link(AbstractMacroAssemblerType* masm) const 729 729 { 730 730 size_t size = m_jumps.size(); 731 731 for (size_t i = 0; i < size; ++i) 732 732 m_jumps[i].link(masm); 733 m_jumps.clear(); 734 } 735 736 void linkTo(Label label, AbstractMacroAssemblerType* masm) 733 } 734 735 void linkTo(Label label, AbstractMacroAssemblerType* masm) const 737 736 { 738 737 size_t size = m_jumps.size(); 739 738 for (size_t i = 0; i < size; ++i) 740 739 m_jumps[i].linkTo(label, masm); 741 m_jumps.clear();742 740 } 743 741 -
trunk/Source/JavaScriptCore/assembler/MacroAssembler.h
r204912 r205462 28 28 29 29 #if ENABLE(ASSEMBLER) 30 31 #include "JSCJSValue.h" 30 32 31 33 #if CPU(ARM_THUMB2) -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
r205283 r205462 167 167 else if (isUInt12(-imm.m_value)) 168 168 m_assembler.sub<32>(dest, src, UInt12(-imm.m_value)); 169 else { 169 else if (src != dest) { 170 move(imm, dest); 171 add32(src, dest); 172 } else { 170 173 move(imm, getCachedDataTempRegisterIDAndInvalidate()); 171 174 m_assembler.add<32>(dest, src, dataTempRegister); -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
r204912 r205462 29 29 #include "Disassembler.h" 30 30 #include "ExecutableAllocator.h" 31 #include "LLIntData.h"32 31 #include <wtf/DataLog.h> 33 32 #include <wtf/PassRefPtr.h> … … 54 53 namespace JSC { 55 54 55 enum OpcodeID : unsigned; 56 56 57 // FunctionPtr: 57 58 // … … 274 275 } 275 276 276 static MacroAssemblerCodePtr createLLIntCodePtr(OpcodeID codeId) 277 { 278 return createFromExecutableAddress(LLInt::getCodePtr(codeId)); 279 } 277 static MacroAssemblerCodePtr createLLIntCodePtr(OpcodeID codeId); 280 278 281 279 explicit MacroAssemblerCodePtr(ReturnAddressPtr ra) … … 300 298 } 301 299 302 void dumpWithName(const char* name, PrintStream& out) const 303 { 304 if (!m_value) { 305 out.print(name, "(null)"); 306 return; 307 } 308 if (executableAddress() == dataLocation()) { 309 out.print(name, "(", RawPointer(executableAddress()), ")"); 310 return; 311 } 312 out.print(name, "(executable = ", RawPointer(executableAddress()), ", dataLocation = ", RawPointer(dataLocation()), ")"); 313 } 314 315 void dump(PrintStream& out) const 316 { 317 dumpWithName("CodePtr", out); 318 } 300 void dumpWithName(const char* name, PrintStream& out) const; 301 302 void dump(PrintStream& out) const; 319 303 320 304 enum EmptyValueTag { EmptyValue }; … … 390 374 391 375 // Helper for creating self-managed code refs from LLInt. 392 static MacroAssemblerCodeRef createLLIntCodeRef(OpcodeID codeId) 393 { 394 return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(codeId))); 395 } 376 static MacroAssemblerCodeRef createLLIntCodeRef(OpcodeID codeId); 396 377 397 378 ExecutableMemoryHandle* executableMemory() const … … 419 400 explicit operator bool() const { return !!m_codePtr; } 420 401 421 void dump(PrintStream& out) const 422 { 423 m_codePtr.dumpWithName("CodeRef", out); 424 } 402 void dump(PrintStream& out) const; 425 403 426 404 private: -
trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp
r204912 r205462 86 86 } 87 87 88 Value* BasicBlock::appendBoolConstant(Procedure& proc, Origin origin, bool value) 89 { 90 return appendIntConstant(proc, origin, Int32, value ? 1 : 0); 91 } 92 88 93 void BasicBlock::clearSuccessors() 89 94 { -
trunk/Source/JavaScriptCore/b3/B3BasicBlock.h
r204912 r205462 83 83 JS_EXPORT_PRIVATE Value* appendIntConstant(Procedure&, Origin, Type, int64_t value); 84 84 Value* appendIntConstant(Procedure&, Value* likeValue, int64_t value); 85 Value* appendBoolConstant(Procedure&, Origin, bool); 85 86 86 87 void removeLast(Procedure&); -
trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp
r204920 r205462 72 72 73 73 for (BasicBlock* block : m_proc) { 74 if (block->size() > m_maxSize || block->numSuccessors() > m_maxSuccessors) 74 if (block->size() > m_maxSize) 75 continue; 76 if (block->numSuccessors() > m_maxSuccessors) 77 continue; 78 if (block->last()->type() != Void) // Demoting doesn't handle terminals with values. 75 79 continue; 76 80 -
trunk/Source/JavaScriptCore/b3/B3StackmapGenerationParams.h
r204912 r205462 93 93 // Returns true if the successor at the given index is going to be emitted right after the 94 94 // patchpoint. 95 bool fallsThroughToSuccessor(unsigned successorIndex) const;95 JS_EXPORT_PRIVATE bool fallsThroughToSuccessor(unsigned successorIndex) const; 96 96 97 97 // This is provided for convenience; it means that you don't have to capture it if you don't want to. -
trunk/Source/JavaScriptCore/b3/testb3.cpp
r204912 r205462 12919 12919 CHECK_EQ(terminal.args[1].kind(), firstKind); 12920 12920 CHECK(terminal.args[2].kind() == Air::Arg::BitImm || terminal.args[2].kind() == Air::Arg::BitImm64); 12921 } 12922 12923 void testPatchpointTerminalReturnValue(bool successIsRare) 12924 { 12925 // This is a unit test for how FTL's heap allocation fast paths behave. 12926 Procedure proc; 12927 12928 BasicBlock* root = proc.addBlock(); 12929 BasicBlock* success = proc.addBlock(); 12930 BasicBlock* slowPath = proc.addBlock(); 12931 BasicBlock* continuation = proc.addBlock(); 12932 12933 Value* arg = root->appendNew<Value>( 12934 proc, Trunc, Origin(), 12935 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)); 12936 12937 PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin()); 12938 patchpoint->effects.terminal = true; 12939 patchpoint->clobber(RegisterSet::macroScratchRegisters()); 12940 12941 if (successIsRare) { 12942 root->appendSuccessor(FrequentedBlock(success, FrequencyClass::Rare)); 12943 root->appendSuccessor(slowPath); 12944 } else { 12945 root->appendSuccessor(success); 12946 root->appendSuccessor(FrequentedBlock(slowPath, FrequencyClass::Rare)); 12947 } 12948 12949 patchpoint->appendSomeRegister(arg); 12950 12951 patchpoint->setGenerator( 12952 [&] (CCallHelpers& jit, const StackmapGenerationParams& params) { 12953 AllowMacroScratchRegisterUsage allowScratch(jit); 12954 12955 CCallHelpers::Jump jumpToSlow = 12956 jit.branch32(CCallHelpers::Above, params[1].gpr(), CCallHelpers::TrustedImm32(42)); 12957 12958 jit.add32(CCallHelpers::TrustedImm32(31), params[1].gpr(), params[0].gpr()); 12959 12960 CCallHelpers::Jump jumpToSuccess; 12961 if (!params.fallsThroughToSuccessor(0)) 12962 jumpToSuccess = jit.jump(); 12963 12964 Vector<Box<CCallHelpers::Label>> labels = params.successorLabels(); 12965 12966 params.addLatePath( 12967 [=] (CCallHelpers& jit) { 12968 jumpToSlow.linkTo(*labels[1], &jit); 12969 if (jumpToSuccess.isSet()) 12970 jumpToSuccess.linkTo(*labels[0], &jit); 12971 }); 12972 }); 12973 12974 UpsilonValue* successUpsilon = success->appendNew<UpsilonValue>(proc, Origin(), patchpoint); 12975 success->appendNew<Value>(proc, Jump, Origin()); 12976 success->setSuccessors(continuation); 12977 12978 UpsilonValue* slowPathUpsilon = slowPath->appendNew<UpsilonValue>( 12979 proc, Origin(), slowPath->appendNew<Const32Value>(proc, Origin(), 666)); 12980 slowPath->appendNew<Value>(proc, Jump, Origin()); 12981 slowPath->setSuccessors(continuation); 12982 12983 Value* phi = continuation->appendNew<Value>(proc, Phi, Int32, Origin()); 12984 successUpsilon->setPhi(phi); 12985 slowPathUpsilon->setPhi(phi); 12986 continuation->appendNew<Value>(proc, Return, Origin(), phi); 12987 12988 auto code = compile(proc); 12989 CHECK_EQ(invoke<int>(*code, 0), 31); 12990 CHECK_EQ(invoke<int>(*code, 1), 32); 12991 CHECK_EQ(invoke<int>(*code, 41), 72); 12992 CHECK_EQ(invoke<int>(*code, 42), 73); 12993 CHECK_EQ(invoke<int>(*code, 43), 666); 12994 CHECK_EQ(invoke<int>(*code, -1), 666); 12921 12995 } 12922 12996 … … 14338 14412 14339 14413 RUN(testSomeEarlyRegister()); 14414 RUN(testPatchpointTerminalReturnValue(true)); 14415 RUN(testPatchpointTerminalReturnValue(false)); 14340 14416 14341 14417 if (isX86()) { -
trunk/Source/JavaScriptCore/bindings/ScriptValue.cpp
r205324 r205462 33 33 #include "APICast.h" 34 34 #include "InspectorValues.h" 35 #include "JSCInlines.h" 35 36 #include "JSLock.h" 36 #include "JSObjectInlines.h"37 #include "StructureInlines.h"38 37 39 38 using namespace JSC; -
trunk/Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp
r204912 r205462 27 27 #include "AdaptiveInferredPropertyValueWatchpointBase.h" 28 28 29 #include "JSCellInlines.h" 30 #include "StructureInlines.h" 29 #include "JSCInlines.h" 31 30 32 31 namespace JSC { -
trunk/Source/JavaScriptCore/bytecode/BytecodeLivenessAnalysis.cpp
r204994 r205462 33 33 #include "FullBytecodeLiveness.h" 34 34 #include "InterpreterInlines.h" 35 #include "PreciseJumpTargets.h" 35 36 36 37 namespace JSC { -
trunk/Source/JavaScriptCore/bytecode/BytecodeRewriter.cpp
r204994 r205462 28 28 #include "BytecodeRewriter.h" 29 29 30 #include "HeapInlines.h" 30 31 #include "PreciseJumpTargetsInlines.h" 31 32 #include <wtf/BubbleSort.h> -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r204994 r205462 28 28 29 29 #include "CodeBlock.h" 30 #include "Interpreter.h" 30 31 31 32 namespace JSC { -
trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.cpp
r204912 r205462 31 31 #include "DFGThunks.h" 32 32 #include "JSCInlines.h" 33 #include "Opcode.h" 33 34 #include "Repatch.h" 34 35 #include <wtf/ListDump.h> … … 36 37 #if ENABLE(JIT) 37 38 namespace JSC { 39 40 CallLinkInfo::CallType CallLinkInfo::callTypeFor(OpcodeID opcodeID) 41 { 42 if (opcodeID == op_call || opcodeID == op_call_eval) 43 return Call; 44 if (opcodeID == op_call_varargs) 45 return CallVarargs; 46 if (opcodeID == op_construct) 47 return Construct; 48 if (opcodeID == op_construct_varargs) 49 return ConstructVarargs; 50 if (opcodeID == op_tail_call) 51 return TailCall; 52 ASSERT(opcodeID == op_tail_call_varargs || op_tail_call_forward_arguments); 53 return TailCallVarargs; 54 } 38 55 39 56 CallLinkInfo::CallLinkInfo() -
trunk/Source/JavaScriptCore/bytecode/CallLinkInfo.h
r204912 r205462 32 32 #include "JITWriteBarrier.h" 33 33 #include "JSFunction.h" 34 #include "Opcode.h"35 34 #include "PolymorphicCallStubRoutine.h" 36 35 #include "WriteBarrier.h" … … 41 40 #if ENABLE(JIT) 42 41 42 enum OpcodeID : unsigned; 43 43 struct CallFrameShuffleData; 44 44 … … 46 46 public: 47 47 enum CallType { None, Call, CallVarargs, Construct, ConstructVarargs, TailCall, TailCallVarargs }; 48 static CallType callTypeFor(OpcodeID opcodeID) 49 { 50 if (opcodeID == op_call || opcodeID == op_call_eval) 51 return Call; 52 if (opcodeID == op_call_varargs) 53 return CallVarargs; 54 if (opcodeID == op_construct) 55 return Construct; 56 if (opcodeID == op_construct_varargs) 57 return ConstructVarargs; 58 if (opcodeID == op_tail_call) 59 return TailCall; 60 ASSERT(opcodeID == op_tail_call_varargs || op_tail_call_forward_arguments); 61 return TailCallVarargs; 62 } 48 static CallType callTypeFor(OpcodeID opcodeID); 63 49 64 50 static bool isVarargsCallType(CallType callType) -
trunk/Source/JavaScriptCore/bytecode/CallLinkStatus.cpp
r204912 r205462 31 31 #include "DFGJITCode.h" 32 32 #include "InlineCallFrame.h" 33 #include "Interpreter.h" 33 34 #include "LLIntCallLinkInfo.h" 34 35 #include "JSCInlines.h" -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r205321 r205462 53 53 #include "JSLexicalEnvironment.h" 54 54 #include "JSModuleEnvironment.h" 55 #include "LLIntData.h" 55 56 #include "LLIntEntrypoint.h" 56 57 #include "LLIntPrototypeLoadAdaptiveStructureWatchpoint.h" … … 71 72 #include <wtf/BagToHashMap.h> 72 73 #include <wtf/CommaPrinter.h> 74 #include <wtf/SimpleStats.h> 73 75 #include <wtf/StringExtras.h> 74 76 #include <wtf/StringPrintStream.h> … … 1877 1879 } 1878 1880 1879 heap()->m_codeBlocks .add(this);1881 heap()->m_codeBlocks->add(this); 1880 1882 } 1881 1883 … … 2343 2345 dumpBytecode(); 2344 2346 2345 heap()->m_codeBlocks .add(this);2347 heap()->m_codeBlocks->add(this); 2346 2348 heap()->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction)); 2347 2349 } … … 2380 2382 Base::finishCreation(vm); 2381 2383 2382 heap()->m_codeBlocks .add(this);2384 heap()->m_codeBlocks->add(this); 2383 2385 } 2384 2386 #endif … … 2782 2784 codeBlock->propagateTransitions(visitor); 2783 2785 codeBlock->determineLiveness(visitor); 2786 } 2787 2788 void CodeBlock::clearLLIntGetByIdCache(Instruction* instruction) 2789 { 2790 instruction[0].u.opcode = LLInt::getOpcode(op_get_by_id); 2791 instruction[4].u.pointer = nullptr; 2792 instruction[5].u.pointer = nullptr; 2793 instruction[6].u.pointer = nullptr; 2784 2794 } 2785 2795 … … 4185 4195 return 0; 4186 4196 4187 if (! m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT)4197 if (!*m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT) 4188 4198 return 0; // It's as good of a prediction as we'll get. 4189 4199 4190 4200 // Be conservative: return a size that will be an overestimation 84% of the time. 4191 double multiplier = m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT .mean() +4192 m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT .standardDeviation();4201 double multiplier = m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->mean() + 4202 m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->standardDeviation(); 4193 4203 4194 4204 // Be paranoid: silently reject bogus multipiers. Silently doing the "wrong" thing -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r204994 r205462 294 294 return m_jitCodeMap.get(); 295 295 } 296 297 static void clearLLIntGetByIdCache(Instruction*); 296 298 297 299 unsigned bytecodeOffset(Instruction* returnAddress) … … 1284 1286 #endif 1285 1287 1286 inline void clearLLIntGetByIdCache(Instruction* instruction)1287 {1288 instruction[0].u.opcode = LLInt::getOpcode(op_get_by_id);1289 instruction[4].u.pointer = nullptr;1290 instruction[5].u.pointer = nullptr;1291 instruction[6].u.pointer = nullptr;1292 }1293 1294 1288 inline Register& ExecState::r(int index) 1295 1289 { -
trunk/Source/JavaScriptCore/bytecode/ExecutionCounter.h
r183506 r205462 30 30 #include "Options.h" 31 31 #include <wtf/PrintStream.h> 32 #include <wtf/SimpleStats.h>33 32 34 33 namespace JSC { -
trunk/Source/JavaScriptCore/bytecode/Instruction.h
r204912 r205462 32 32 #include "BasicBlockLocation.h" 33 33 #include "MacroAssembler.h" 34 #include "Opcode.h"35 34 #include "PutByIdFlags.h" 36 35 #include "SymbolTable.h" … … 52 51 struct LLIntCallLinkInfo; 53 52 struct ValueProfile; 53 54 #if ENABLE(COMPUTED_GOTO_OPCODES) 55 typedef void* Opcode; 56 #else 57 typedef OpcodeID Opcode; 58 #endif 54 59 55 60 struct Instruction { -
trunk/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp
r204912 r205462 29 29 #include "CodeBlock.h" 30 30 #include "Instruction.h" 31 #include " StructureInlines.h"31 #include "JSCInlines.h" 32 32 33 33 namespace JSC { … … 60 60 StringFireDetail stringDetail(out.toCString().data()); 61 61 62 clearLLIntGetByIdCache(m_getByIdInstruction);62 CodeBlock::clearLLIntGetByIdCache(m_getByIdInstruction); 63 63 } 64 64 -
trunk/Source/JavaScriptCore/bytecode/ObjectAllocationProfile.h
r204912 r205462 46 46 } 47 47 48 bool isNull() { return !m_ allocator; }48 bool isNull() { return !m_structure; } 49 49 50 50 void initialize(VM& vm, JSCell* owner, JSObject* prototype, unsigned inferredInlineCapacity) … … 81 81 82 82 size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity); 83 MarkedAllocator* allocator = &vm.heap.allocatorForObjectWithoutDestructor(allocationSize); 84 ASSERT(allocator->cellSize()); 85 83 MarkedAllocator* allocator = vm.heap.allocatorForObjectWithoutDestructor(allocationSize); 84 86 85 // Take advantage of extra inline capacity available in the size class. 87 size_t slop = (allocator->cellSize() - allocationSize) / sizeof(WriteBarrier<Unknown>); 88 inlineCapacity += slop; 89 if (inlineCapacity > JSFinalObject::maxInlineCapacity()) 90 inlineCapacity = JSFinalObject::maxInlineCapacity(); 86 if (allocator) { 87 size_t slop = (allocator->cellSize() - allocationSize) / sizeof(WriteBarrier<Unknown>); 88 inlineCapacity += slop; 89 if (inlineCapacity > JSFinalObject::maxInlineCapacity()) 90 inlineCapacity = JSFinalObject::maxInlineCapacity(); 91 } 91 92 92 93 Structure* structure = vm.prototypeMap.emptyObjectStructureForPrototype(prototype, inlineCapacity); -
trunk/Source/JavaScriptCore/bytecode/Opcode.h
r204994 r205462 56 56 57 57 #define OPCODE_ID_ENUM(opcode, length) opcode, 58 typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID;58 enum OpcodeID : unsigned { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) }; 59 59 #undef OPCODE_ID_ENUM 60 60 -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
r204912 r205462 1207 1207 1208 1208 if (allocatingInline) { 1209 CopiedAllocator* copiedAllocator = &vm.heap.storageAllocator(); 1210 1211 if (!reallocating) { 1212 jit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR); 1213 slowPath.append( 1214 jit.branchSubPtr( 1215 CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR)); 1216 jit.storePtr(scratchGPR, &copiedAllocator->m_currentRemaining); 1217 jit.negPtr(scratchGPR); 1218 jit.addPtr( 1219 CCallHelpers::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR); 1220 jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR); 1221 } else { 1209 MarkedAllocator* allocator = vm.heap.allocatorForAuxiliaryData(newSize); 1210 1211 if (!allocator) { 1212 // Yuck, this case would suck! 1213 slowPath.append(jit.jump()); 1214 } 1215 1216 jit.move(CCallHelpers::TrustedImmPtr(allocator), scratchGPR2); 1217 jit.emitAllocate(scratchGPR, allocator, scratchGPR2, scratchGPR3, slowPath); 1218 jit.addPtr(CCallHelpers::TrustedImm32(newSize + sizeof(IndexingHeader)), scratchGPR); 1219 1220 if (reallocating) { 1222 1221 // Handle the case where we are reallocating (i.e. the old structure/butterfly 1223 1222 // already had out-of-line property storage). … … 1226 1225 1227 1226 jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR3); 1228 jit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR); 1229 slowPath.append( 1230 jit.branchSubPtr( 1231 CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR)); 1232 jit.storePtr(scratchGPR, &copiedAllocator->m_currentRemaining); 1233 jit.negPtr(scratchGPR); 1234 jit.addPtr( 1235 CCallHelpers::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR); 1236 jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR); 1227 1237 1228 // We have scratchGPR = new storage, scratchGPR3 = old storage, 1238 1229 // scratchGPR2 = available … … 1660 1651 for (unsigned i = cases.size(); i--;) { 1661 1652 fallThrough.link(&jit); 1653 fallThrough.clear(); 1662 1654 cases[i]->generateWithGuard(state, fallThrough); 1663 1655 } -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h
r204912 r205462 30 30 31 31 #include "CodeOrigin.h" 32 #include "JITStubRoutine.h" 32 33 #include "JSFunctionInlines.h" 33 34 #include "MacroAssembler.h" 34 35 #include "ObjectPropertyConditionSet.h" 35 #include "Opcode.h"36 36 #include "ScratchRegisterAllocator.h" 37 37 #include "Structure.h" -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
r204912 r205462 28 28 29 29 #include "JSObject.h" 30 #include "JSCInlines.h" 30 31 #include "PolymorphicAccess.h" 31 32 #include "Repatch.h" -
trunk/Source/JavaScriptCore/bytecode/StructureStubInfo.h
r204912 r205462 32 32 #include "MacroAssembler.h" 33 33 #include "ObjectPropertyConditionSet.h" 34 #include "Opcode.h"35 34 #include "Options.h" 36 35 #include "RegisterSet.h" -
trunk/Source/JavaScriptCore/bytecode/SuperSampler.cpp
r198396 r205462 37 37 volatile uint32_t g_superSamplerCount; 38 38 39 static StaticLock lock; 39 40 static double in; 40 41 static double out; … … 52 53 for (;;) { 53 54 for (int ms = 0; ms < printingPeriod; ms += sleepQuantum) { 54 if (g_superSamplerCount) 55 in++; 56 else 57 out++; 55 { 56 LockHolder locker(lock); 57 if (g_superSamplerCount) 58 in++; 59 else 60 out++; 61 } 58 62 sleepMS(sleepQuantum); 59 63 } … … 65 69 } 66 70 71 void resetSuperSamplerState() 72 { 73 LockHolder locker(lock); 74 in = 0; 75 out = 0; 76 } 77 67 78 void printSuperSamplerState() 68 79 { … … 70 81 return; 71 82 83 LockHolder locker(lock); 72 84 double percentage = 100.0 * in / (in + out); 73 85 if (percentage != percentage) -
trunk/Source/JavaScriptCore/bytecode/SuperSampler.h
r198364 r205462 54 54 }; 55 55 56 JS_EXPORT_PRIVATE void resetSuperSamplerState(); 56 57 JS_EXPORT_PRIVATE void printSuperSamplerState(); 57 58 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
r204994 r205462 91 91 } 92 92 93 VM* UnlinkedCodeBlock::vm() const94 {95 return MarkedBlock::blockFor(this)->vm();96 }97 98 93 void UnlinkedCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor) 99 94 { -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r204994 r205462 284 284 void addExceptionHandler(const UnlinkedHandlerInfo& handler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(handler); } 285 285 UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; } 286 287 VM* vm() const;288 286 289 287 UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; } -
trunk/Source/JavaScriptCore/bytecode/UnlinkedInstructionStream.cpp
r204912 r205462 26 26 #include "config.h" 27 27 #include "UnlinkedInstructionStream.h" 28 29 #include "Opcode.h" 28 30 29 31 namespace JSC { -
trunk/Source/JavaScriptCore/bytecode/UnlinkedInstructionStream.h
r204912 r205462 28 28 #define UnlinkedInstructionStream_h 29 29 30 #include "Opcode.h" 30 31 #include "UnlinkedCodeBlock.h" 31 32 #include <wtf/RefCountedArray.h> -
trunk/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h
r204439 r205462 39 39 public: 40 40 CallArrayAllocatorSlowPathGenerator( 41 MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZ function,41 MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZB function, 42 42 GPRReg resultGPR, GPRReg storageGPR, Structure* structure, size_t size) 43 43 : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit) … … 58 58 for (unsigned i = 0; i < m_plans.size(); ++i) 59 59 jit->silentSpill(m_plans[i]); 60 jit->callOperation(m_function, m_resultGPR, m_structure, m_size );60 jit->callOperation(m_function, m_resultGPR, m_structure, m_size, m_storageGPR); 61 61 GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); 62 62 for (unsigned i = m_plans.size(); i--;) … … 68 68 69 69 private: 70 P_JITOperation_EStZ m_function;70 P_JITOperation_EStZB m_function; 71 71 GPRReg m_resultGPR; 72 72 GPRReg m_storageGPR; … … 79 79 public: 80 80 CallArrayAllocatorWithVariableSizeSlowPathGenerator( 81 MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZ function,82 GPRReg resultGPR, Structure* contiguousStructure, Structure* arrayStorageStructure, GPRReg sizeGPR )81 MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZB function, 82 GPRReg resultGPR, Structure* contiguousStructure, Structure* arrayStorageStructure, GPRReg sizeGPR, GPRReg storageGPR) 83 83 : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit) 84 84 , m_function(function) … … 87 87 , m_arrayStorageOrContiguousStructure(arrayStorageStructure) 88 88 , m_sizeGPR(sizeGPR) 89 , m_storageGPR(storageGPR) 89 90 { 90 91 jit->silentSpillAllRegistersImpl(false, m_plans, resultGPR); … … 97 98 for (unsigned i = 0; i < m_plans.size(); ++i) 98 99 jit->silentSpill(m_plans[i]); 99 GPRReg scratchGPR = AssemblyHelpers::selectScratchGPR(m_sizeGPR );100 GPRReg scratchGPR = AssemblyHelpers::selectScratchGPR(m_sizeGPR, m_storageGPR); 100 101 if (m_contiguousStructure != m_arrayStorageOrContiguousStructure) { 101 102 MacroAssembler::Jump bigLength = jit->m_jit.branch32(MacroAssembler::AboveOrEqual, m_sizeGPR, MacroAssembler::TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)); … … 107 108 } else 108 109 jit->m_jit.move(MacroAssembler::TrustedImmPtr(m_contiguousStructure), scratchGPR); 109 jit->callOperation(m_function, m_resultGPR, scratchGPR, m_sizeGPR );110 jit->callOperation(m_function, m_resultGPR, scratchGPR, m_sizeGPR, m_storageGPR); 110 111 GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); 111 112 for (unsigned i = m_plans.size(); i--;) … … 116 117 117 118 private: 118 P_JITOperation_EStZ m_function;119 P_JITOperation_EStZB m_function; 119 120 GPRReg m_resultGPR; 120 121 Structure* m_contiguousStructure; 121 122 Structure* m_arrayStorageOrContiguousStructure; 122 123 GPRReg m_sizeGPR; 124 GPRReg m_storageGPR; 123 125 Vector<SilentRegisterSavePlan, 2> m_plans; 124 126 }; -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r205198 r205462 934 934 } 935 935 936 char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size )937 { 938 VM * vm = &exec->vm();939 NativeCallFrameTracer tracer( vm, exec);940 auto scope = DECLARE_THROW_SCOPE( *vm);936 char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size, Butterfly* butterfly) 937 { 938 VM& vm = exec->vm(); 939 NativeCallFrameTracer tracer(&vm, exec); 940 auto scope = DECLARE_THROW_SCOPE(vm); 941 941 942 942 if (UNLIKELY(size < 0)) 943 943 return bitwise_cast<char*>(throwException(exec, scope, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer.")))); 944 944 945 JSArray* result = JSArray::create(*vm, arrayStructure, size); 946 result->butterfly(); // Ensure that the backing store is in to-space. 945 JSArray* result; 946 if (butterfly) 947 result = JSArray::createWithButterfly(vm, arrayStructure, butterfly); 948 else 949 result = JSArray::create(vm, arrayStructure, size); 947 950 return bitwise_cast<char*>(result); 948 951 } … … 1630 1633 } 1631 1634 1632 char* JIT_OPERATION operationNewRawObject(ExecState* exec, Structure* structure, int32_t length )1633 { 1634 VM& vm = exec->vm(); 1635 NativeCallFrameTracer tracer(&vm, exec); 1636 1637 Butterfly* butterfly;1638 if (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType())) {1635 char* JIT_OPERATION operationNewRawObject(ExecState* exec, Structure* structure, int32_t length, Butterfly* butterfly) 1636 { 1637 VM& vm = exec->vm(); 1638 NativeCallFrameTracer tracer(&vm, exec); 1639 1640 if (!butterfly 1641 && (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType()))) { 1639 1642 IndexingHeader header; 1640 1643 header.setVectorLength(length); … … 1645 1648 hasIndexedProperties(structure->indexingType()), header, 1646 1649 length * sizeof(EncodedJSValue)); 1647 } else 1648 butterfly = nullptr; 1650 } 1649 1651 1650 1652 JSObject* result = JSObject::createRawObject(exec, structure, butterfly); … … 1653 1655 } 1654 1656 1655 JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure) 1656 { 1657 VM& vm = exec->vm(); 1658 NativeCallFrameTracer tracer(&vm, exec); 1659 1660 Butterfly* butterfly = Butterfly::create( 1661 vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0); 1657 JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState* exec, Structure* structure, Butterfly* butterfly) 1658 { 1659 VM& vm = exec->vm(); 1660 NativeCallFrameTracer tracer(&vm, exec); 1661 1662 if (!butterfly) { 1663 butterfly = Butterfly::create( 1664 vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0); 1665 } 1662 1666 1663 1667 JSObject* result = JSObject::createRawObject(exec, structure, butterfly); … … 1666 1670 } 1667 1671 1668 JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState* exec, Structure* structure, unsigned length )1672 JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState* exec, Structure* structure, unsigned length, Butterfly* butterfly) 1669 1673 { 1670 1674 VM& vm = exec->vm(); … … 1674 1678 header.setVectorLength(length); 1675 1679 header.setPublicLength(0); 1676 Butterfly* butterfly = Butterfly::create( 1677 vm, nullptr, 0, structure->outOfLineCapacity(), true, header, 1678 sizeof(EncodedJSValue) * length); 1679 1680 if (butterfly) 1681 *butterfly->indexingHeader() = header; 1682 else { 1683 butterfly = Butterfly::create( 1684 vm, nullptr, 0, structure->outOfLineCapacity(), true, header, 1685 sizeof(EncodedJSValue) * length); 1686 } 1687 1680 1688 // Paradoxically this may allocate a JSArray. That's totally cool. 1681 1689 JSObject* result = JSObject::createRawObject(exec, structure, butterfly); -
trunk/Source/JavaScriptCore/dfg/DFGOperations.h
r205112 r205462 71 71 char* JIT_OPERATION operationNewArrayBuffer(ExecState*, Structure*, size_t, size_t) WTF_INTERNAL; 72 72 char* JIT_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL; 73 char* JIT_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t ) WTF_INTERNAL;73 char* JIT_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t, Butterfly*) WTF_INTERNAL; 74 74 char* JIT_OPERATION operationNewInt8ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL; 75 75 char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL; … … 177 177 size_t JIT_OPERATION operationDefaultHasInstance(ExecState*, JSCell* value, JSCell* proto); 178 178 179 char* JIT_OPERATION operationNewRawObject(ExecState*, Structure*, int32_t ) WTF_INTERNAL;180 JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState*, Structure* ) WTF_INTERNAL;181 JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState*, Structure*, unsigned length ) WTF_INTERNAL;179 char* JIT_OPERATION operationNewRawObject(ExecState*, Structure*, int32_t, Butterfly*) WTF_INTERNAL; 180 JSCell* JIT_OPERATION operationNewObjectWithButterfly(ExecState*, Structure*, Butterfly*) WTF_INTERNAL; 181 JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(ExecState*, Structure*, unsigned length, Butterfly*) WTF_INTERNAL; 182 182 183 183 void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r205364 r205462 95 95 96 96 ASSERT(vectorLength >= numElements); 97 vectorLength = std::max(BASE_VECTOR_LEN, vectorLength);97 vectorLength = Butterfly::optimalContiguousVectorLength(structure, vectorLength); 98 98 99 99 JITCompiler::JumpList slowCases; … … 104 104 size += outOfLineCapacity * sizeof(JSValue); 105 105 106 m_jit.move(TrustedImmPtr(0), storageGPR); 107 106 108 if (size) { 107 slowCases.append( 108 emitAllocateBasicStorage(TrustedImm32(size), storageGPR)); 109 if (hasIndexingHeader) 110 m_jit.subPtr(TrustedImm32(vectorLength * sizeof(JSValue)), storageGPR); 111 else 112 m_jit.addPtr(TrustedImm32(sizeof(IndexingHeader)), storageGPR); 109 if (MarkedAllocator* allocator = m_jit.vm()->heap.allocatorForAuxiliaryData(size)) { 110 m_jit.move(TrustedImmPtr(allocator), scratchGPR); 111 m_jit.emitAllocate(storageGPR, allocator, scratchGPR, scratch2GPR, slowCases); 112 113 m_jit.addPtr( 114 TrustedImm32(outOfLineCapacity * sizeof(JSValue) + sizeof(IndexingHeader)), 115 storageGPR); 116 117 if (hasIndexingHeader) 118 m_jit.store32(TrustedImm32(vectorLength), MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); 119 } else 120 slowCases.append(m_jit.jump()); 121 } 122 123 size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity); 124 MarkedAllocator* allocatorPtr = m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize); 125 if (allocatorPtr) { 126 m_jit.move(TrustedImmPtr(allocatorPtr), scratchGPR); 127 emitAllocateJSObject(resultGPR, allocatorPtr, scratchGPR, TrustedImmPtr(structure), storageGPR, scratch2GPR, slowCases); 113 128 } else 114 m_jit.move(TrustedImmPtr(0), storageGPR); 115 116 size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity); 117 MarkedAllocator* allocatorPtr = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize); 118 m_jit.move(TrustedImmPtr(allocatorPtr), scratchGPR); 119 emitAllocateJSObject(resultGPR, scratchGPR, TrustedImmPtr(structure), storageGPR, scratch2GPR, slowCases); 120 121 if (hasIndexingHeader) 122 m_jit.store32(TrustedImm32(vectorLength), MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); 129 slowCases.append(m_jit.jump()); 123 130 124 131 // I want a slow path that also loads out the storage pointer, and that's … … 129 136 structure, vectorLength)); 130 137 131 if ( hasDouble(structure->indexingType()) &&numElements < vectorLength) {138 if (numElements < vectorLength) { 132 139 #if USE(JSVALUE64) 133 m_jit.move(TrustedImm64(bitwise_cast<int64_t>(PNaN)), scratchGPR); 140 if (hasDouble(structure->indexingType())) 141 m_jit.move(TrustedImm64(bitwise_cast<int64_t>(PNaN)), scratchGPR); 142 else 143 m_jit.move(TrustedImm64(JSValue::encode(JSValue())), scratchGPR); 134 144 for (unsigned i = numElements; i < vectorLength; ++i) 135 145 m_jit.store64(scratchGPR, MacroAssembler::Address(storageGPR, sizeof(double) * i)); 136 146 #else 137 147 EncodedValueDescriptor value; 138 value.asInt64 = JSValue::encode(JSValue(JSValue::EncodeAsDouble, PNaN)); 148 if (hasDouble(structure->indexingType())) 149 value.asInt64 = JSValue::encode(JSValue(JSValue::EncodeAsDouble, PNaN)); 150 else 151 value.asInt64 = JSValue::encode(JSValue()); 139 152 for (unsigned i = numElements; i < vectorLength; ++i) { 140 153 m_jit.store32(TrustedImm32(value.asBits.tag), MacroAssembler::Address(storageGPR, sizeof(double) * i + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); … … 3824 3837 3825 3838 JITCompiler::JumpList slowPath; 3826 MarkedAllocator& markedAllocator = m_jit.vm()->heap.allocatorForObjectWithDestructor(sizeof(JSRopeString)); 3827 m_jit.move(TrustedImmPtr(&markedAllocator), allocatorGPR); 3828 emitAllocateJSCell(resultGPR, allocatorGPR, TrustedImmPtr(m_jit.vm()->stringStructure.get()), scratchGPR, slowPath); 3839 MarkedAllocator* markedAllocator = m_jit.vm()->heap.allocatorForObjectWithDestructor(sizeof(JSRopeString)); 3840 RELEASE_ASSERT(markedAllocator); 3841 m_jit.move(TrustedImmPtr(markedAllocator), allocatorGPR); 3842 emitAllocateJSCell(resultGPR, markedAllocator, allocatorGPR, TrustedImmPtr(m_jit.vm()->stringStructure.get()), scratchGPR, slowPath); 3829 3843 3830 3844 m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(resultGPR, JSString::offsetOfValue())); … … 6909 6923 void SpeculativeJIT::compileAllocatePropertyStorage(Node* node) 6910 6924 { 6911 if (node->transition()->previous->couldHaveIndexingHeader()) { 6925 ASSERT(!node->transition()->previous->outOfLineCapacity()); 6926 ASSERT(initialOutOfLineCapacity == node->transition()->next->outOfLineCapacity()); 6927 6928 size_t size = initialOutOfLineCapacity * sizeof(JSValue); 6929 6930 MarkedAllocator* allocator = m_jit.vm()->heap.allocatorForAuxiliaryData(size); 6931 6932 if (!allocator || node->transition()->previous->couldHaveIndexingHeader()) { 6912 6933 SpeculateCellOperand base(this, node->child1()); 6913 6934 … … 6926 6947 SpeculateCellOperand base(this, node->child1()); 6927 6948 GPRTemporary scratch1(this); 6949 GPRTemporary scratch2(this); 6950 GPRTemporary scratch3(this); 6928 6951 6929 6952 GPRReg baseGPR = base.gpr(); 6930 6953 GPRReg scratchGPR1 = scratch1.gpr(); 6931 6932 ASSERT(!node->transition()->previous->outOfLineCapacity()); 6933 ASSERT(initialOutOfLineCapacity == node->transition()->next->outOfLineCapacity()); 6934 6935 JITCompiler::Jump slowPath = 6936 emitAllocateBasicStorage( 6937 TrustedImm32(initialOutOfLineCapacity * sizeof(JSValue)), scratchGPR1); 6938 6939 m_jit.addPtr(JITCompiler::TrustedImm32(sizeof(IndexingHeader)), scratchGPR1); 6954 GPRReg scratchGPR2 = scratch2.gpr(); 6955 GPRReg scratchGPR3 = scratch3.gpr(); 6956 6957 m_jit.move(JITCompiler::TrustedImmPtr(allocator), scratchGPR2); 6958 JITCompiler::JumpList slowPath; 6959 m_jit.emitAllocate(scratchGPR1, allocator, scratchGPR2, scratchGPR3, slowPath); 6960 m_jit.addPtr(JITCompiler::TrustedImm32(size + sizeof(IndexingHeader)), scratchGPR1); 6940 6961 6941 6962 addSlowPathGenerator( … … 6952 6973 size_t newSize = oldSize * outOfLineGrowthFactor; 6953 6974 ASSERT(newSize == node->transition()->next->outOfLineCapacity() * sizeof(JSValue)); 6954 6955 if (node->transition()->previous->couldHaveIndexingHeader()) { 6975 6976 MarkedAllocator* allocator = m_jit.vm()->heap.allocatorForAuxiliaryData(newSize); 6977 6978 if (!allocator || node->transition()->previous->couldHaveIndexingHeader()) { 6956 6979 SpeculateCellOperand base(this, node->child1()); 6957 6980 … … 6972 6995 GPRTemporary scratch1(this); 6973 6996 GPRTemporary scratch2(this); 6997 GPRTemporary scratch3(this); 6974 6998 6975 6999 GPRReg baseGPR = base.gpr(); … … 6977 7001 GPRReg scratchGPR1 = scratch1.gpr(); 6978 7002 GPRReg scratchGPR2 = scratch2.gpr(); 6979 6980 JITCompiler::Jump slowPath = 6981 emitAllocateBasicStorage(TrustedImm32(newSize), scratchGPR1); 6982 6983 m_jit.addPtr(JITCompiler::TrustedImm32(sizeof(IndexingHeader)), scratchGPR1); 7003 GPRReg scratchGPR3 = scratch3.gpr(); 7004 7005 JITCompiler::JumpList slowPath; 7006 m_jit.move(JITCompiler::TrustedImmPtr(allocator), scratchGPR2); 7007 m_jit.emitAllocate(scratchGPR1, allocator, scratchGPR2, scratchGPR3, slowPath); 7008 7009 m_jit.addPtr(JITCompiler::TrustedImm32(newSize + sizeof(IndexingHeader)), scratchGPR1); 6984 7010 6985 7011 addSlowPathGenerator( -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r205112 r205462 1002 1002 { 1003 1003 m_jit.setupArgumentsWithExecState(arg1, arg2); 1004 return appendCallSetResult(operation, result); 1005 } 1006 JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, Structure* structure, GPRReg arg2, GPRReg butterfly) 1007 { 1008 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2, butterfly); 1009 return appendCallSetResult(operation, result); 1010 } 1011 JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, Structure* structure, size_t arg2, GPRReg butterfly) 1012 { 1013 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2), butterfly); 1014 return appendCallSetResult(operation, result); 1015 } 1016 JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg butterfly) 1017 { 1018 m_jit.setupArgumentsWithExecState(arg1, arg2, butterfly); 1019 return appendCallSetResult(operation, result); 1020 } 1021 JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, GPRReg arg1, GPRReg arg2, Butterfly* butterfly) 1022 { 1023 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(butterfly)); 1004 1024 return appendCallSetResult(operation, result); 1005 1025 } … … 2558 2578 // Allocator for a cell of a specific size. 2559 2579 template <typename StructureType> // StructureType can be GPR or ImmPtr. 2560 void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure, 2580 void emitAllocateJSCell( 2581 GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, StructureType structure, 2561 2582 GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) 2562 2583 { 2563 m_jit.emitAllocateJSCell(resultGPR, allocator GPR, structure, scratchGPR, slowPath);2584 m_jit.emitAllocateJSCell(resultGPR, allocator, allocatorGPR, structure, scratchGPR, slowPath); 2564 2585 } 2565 2586 2566 2587 // Allocator for an object of a specific size. 2567 2588 template <typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr. 2568 void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure, 2589 void emitAllocateJSObject( 2590 GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, StructureType structure, 2569 2591 StorageType storage, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) 2570 2592 { 2571 m_jit.emitAllocateJSObject(resultGPR, allocatorGPR, structure, storage, scratchGPR, slowPath); 2593 m_jit.emitAllocateJSObject( 2594 resultGPR, allocator, allocatorGPR, structure, storage, scratchGPR, slowPath); 2572 2595 } 2573 2596 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r205112 r205462 3867 3867 m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR); 3868 3868 done.link(&m_jit); 3869 callOperation( 3870 operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR); 3869 callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR, nullptr); 3871 3870 m_jit.exceptionCheck(); 3872 3871 cellResult(resultGPR, node); … … 4034 4033 m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR); 4035 4034 slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, allocatorGPR)); 4036 emitAllocateJSObject(resultGPR, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath);4035 emitAllocateJSObject(resultGPR, nullptr, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath); 4037 4036 4038 4037 addSlowPathGenerator(slowPathCall(slowPath, this, operationCreateThis, resultGPR, calleeGPR, node->inlineCapacity())); … … 4055 4054 Structure* structure = node->structure(); 4056 4055 size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity()); 4057 MarkedAllocator* allocatorPtr = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize);4056 MarkedAllocator* allocatorPtr = m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize); 4058 4057 4059 4058 m_jit.move(TrustedImmPtr(allocatorPtr), allocatorGPR); 4060 emitAllocateJSObject(resultGPR, allocator GPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath);4059 emitAllocateJSObject(resultGPR, allocatorPtr, allocatorGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath); 4061 4060 4062 4061 addSlowPathGenerator(slowPathCall(slowPath, this, operationNewObject, resultGPR, structure)); … … 5365 5364 GPRReg scratch2GPR = scratch2.gpr(); 5366 5365 5366 m_jit.move(TrustedImmPtr(0), storageGPR); 5367 5367 5368 MacroAssembler::JumpList slowCases; 5368 5369 if (shouldConvertLargeSizeToArrayStorage) 5369 5370 slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH))); 5370 5371 5371 5372 ASSERT((1 << 3) == sizeof(JSValue)); 5372 5373 m_jit.move(sizeGPR, scratchGPR); 5373 5374 m_jit.lshift32(TrustedImm32(3), scratchGPR); 5374 5375 m_jit.add32(TrustedImm32(sizeof(IndexingHeader)), scratchGPR, resultGPR); 5375 slowCases.append( 5376 emitAllocateBasicStorage(resultGPR, storageGPR)); 5377 m_jit.subPtr(scratchGPR, storageGPR); 5376 m_jit.emitAllocateVariableSized( 5377 storageGPR, m_jit.vm()->heap.subspaceForAuxiliaryData(), resultGPR, scratchGPR, 5378 scratch2GPR, slowCases); 5379 m_jit.addPtr(TrustedImm32(sizeof(IndexingHeader)), storageGPR); 5380 5381 m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); 5382 m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); 5383 5384 JSValue hole; 5385 if (hasDouble(indexingType)) 5386 hole = JSValue(JSValue::EncodeAsDouble, PNaN); 5387 else 5388 hole = JSValue(); 5389 5390 m_jit.move(sizeGPR, scratchGPR); 5391 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratchGPR); 5392 MacroAssembler::Label loop = m_jit.label(); 5393 m_jit.sub32(TrustedImm32(1), scratchGPR); 5394 m_jit.store32(TrustedImm32(hole.u.asBits.tag), MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); 5395 m_jit.store32(TrustedImm32(hole.u.asBits.payload), MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); 5396 m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit); 5397 done.link(&m_jit); 5398 5378 5399 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType); 5379 5400 emitAllocateJSObject<JSArray>(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases); 5380 5381 m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); 5382 m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); 5383 5384 if (hasDouble(indexingType)) { 5385 JSValue nan = JSValue(JSValue::EncodeAsDouble, PNaN); 5386 5387 m_jit.move(sizeGPR, scratchGPR); 5388 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratchGPR); 5389 MacroAssembler::Label loop = m_jit.label(); 5390 m_jit.sub32(TrustedImm32(1), scratchGPR); 5391 m_jit.store32(TrustedImm32(nan.u.asBits.tag), MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); 5392 m_jit.store32(TrustedImm32(nan.u.asBits.payload), MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); 5393 m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit); 5394 done.link(&m_jit); 5395 } 5396 5401 5397 5402 addSlowPathGenerator(std::make_unique<CallArrayAllocatorWithVariableSizeSlowPathGenerator>( 5398 5403 slowCases, this, operationNewArrayWithSize, resultGPR, 5399 5404 structure, 5400 5405 shouldConvertLargeSizeToArrayStorage ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : structure, 5401 sizeGPR ));5406 sizeGPR, storageGPR)); 5402 5407 } 5403 5408 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r205112 r205462 3819 3819 m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR); 3820 3820 done.link(&m_jit); 3821 callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR );3821 callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR, nullptr); 3822 3822 m_jit.exceptionCheck(); 3823 3823 cellResult(resultGPR, node); … … 3976 3976 m_jit.loadPtr(JITCompiler::Address(rareDataGPR, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()), structureGPR); 3977 3977 slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, allocatorGPR)); 3978 emitAllocateJSObject(resultGPR, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath);3978 emitAllocateJSObject(resultGPR, nullptr, allocatorGPR, structureGPR, TrustedImmPtr(0), scratchGPR, slowPath); 3979 3979 3980 3980 addSlowPathGenerator(slowPathCall(slowPath, this, operationCreateThis, resultGPR, calleeGPR, node->inlineCapacity())); … … 3997 3997 Structure* structure = node->structure(); 3998 3998 size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity()); 3999 MarkedAllocator* allocatorPtr = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize);3999 MarkedAllocator* allocatorPtr = m_jit.vm()->heap.allocatorForObjectWithoutDestructor(allocationSize); 4000 4000 4001 4001 m_jit.move(TrustedImmPtr(allocatorPtr), allocatorGPR); 4002 emitAllocateJSObject(resultGPR, allocator GPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath);4002 emitAllocateJSObject(resultGPR, allocatorPtr, allocatorGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, slowPath); 4003 4003 4004 4004 addSlowPathGenerator(slowPathCall(slowPath, this, operationNewObject, resultGPR, structure)); … … 5237 5237 unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex; 5238 5238 auto triggerIterator = m_jit.jitCode()->tierUpEntryTriggers.find(bytecodeIndex); 5239 RELEASE_ASSERT(triggerIterator != m_jit.jitCode()->tierUpEntryTriggers.end());5239 DFG_ASSERT(m_jit.graph(), node, triggerIterator != m_jit.jitCode()->tierUpEntryTriggers.end()); 5240 5240 uint8_t* forceEntryTrigger = &(m_jit.jitCode()->tierUpEntryTriggers.find(bytecodeIndex)->value); 5241 5241 … … 5421 5421 GPRReg scratch2GPR = scratch2.gpr(); 5422 5422 5423 m_jit.move(TrustedImmPtr(0), storageGPR); 5424 5423 5425 MacroAssembler::JumpList slowCases; 5424 5426 if (shouldConvertLargeSizeToArrayStorage) 5425 5427 slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH))); 5426 5428 5427 5429 ASSERT((1 << 3) == sizeof(JSValue)); 5428 5430 m_jit.move(sizeGPR, scratchGPR); 5429 5431 m_jit.lshift32(TrustedImm32(3), scratchGPR); 5430 5432 m_jit.add32(TrustedImm32(sizeof(IndexingHeader)), scratchGPR, resultGPR); 5431 slowCases.append( 5432 emitAllocateBasicStorage(resultGPR, storageGPR)); 5433 m_jit.subPtr(scratchGPR, storageGPR); 5434 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType); 5435 emitAllocateJSObject<JSArray>(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases); 5436 5433 m_jit.emitAllocateVariableSized( 5434 storageGPR, m_jit.vm()->heap.subspaceForAuxiliaryData(), resultGPR, scratchGPR, 5435 scratch2GPR, slowCases); 5436 m_jit.addPtr(TrustedImm32(sizeof(IndexingHeader)), storageGPR); 5437 5437 5438 m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); 5438 5439 m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); 5439 5440 if (hasDouble(indexingType)) {5440 5441 if (hasDouble(indexingType)) 5441 5442 m_jit.move(TrustedImm64(bitwise_cast<int64_t>(PNaN)), scratchGPR); 5442 m_jit.move(sizeGPR, scratch2GPR); 5443 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratch2GPR); 5444 MacroAssembler::Label loop = m_jit.label(); 5445 m_jit.sub32(TrustedImm32(1), scratch2GPR); 5446 m_jit.store64(scratchGPR, MacroAssembler::BaseIndex(storageGPR, scratch2GPR, MacroAssembler::TimesEight)); 5447 m_jit.branchTest32(MacroAssembler::NonZero, scratch2GPR).linkTo(loop, &m_jit); 5448 done.link(&m_jit); 5449 } 5443 else 5444 m_jit.move(TrustedImm64(JSValue::encode(JSValue())), scratchGPR); 5445 m_jit.move(sizeGPR, scratch2GPR); 5446 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratch2GPR); 5447 MacroAssembler::Label loop = m_jit.label(); 5448 m_jit.sub32(TrustedImm32(1), scratch2GPR); 5449 m_jit.store64(scratchGPR, MacroAssembler::BaseIndex(storageGPR, scratch2GPR, MacroAssembler::TimesEight)); 5450 m_jit.branchTest32(MacroAssembler::NonZero, scratch2GPR).linkTo(loop, &m_jit); 5451 done.link(&m_jit); 5452 5453 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType); 5454 5455 emitAllocateJSObject<JSArray>(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases); 5450 5456 5451 5457 addSlowPathGenerator(std::make_unique<CallArrayAllocatorWithVariableSizeSlowPathGenerator>( … … 5453 5459 structure, 5454 5460 shouldConvertLargeSizeToArrayStorage ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : structure, 5455 sizeGPR ));5461 sizeGPR, storageGPR)); 5456 5462 } 5457 5463 -
trunk/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
r204958 r205462 41 41 #include "StringPrototype.h" 42 42 #include <cstdlib> 43 #include <wtf/text/StringBuilder.h> 43 44 44 45 namespace JSC { namespace DFG { … … 421 422 break; 422 423 } 423 424 424 425 unsigned lastIndex; 425 426 if (regExp->globalOrSticky()) { … … 469 470 470 471 MatchResult result; 471 Vector<int , 32> ovector;472 Vector<int> ovector; 472 473 // We have to call the kind of match function that the main thread would have called. 473 474 // Otherwise, we might not have the desired Yarr code compiled, and the match will fail. … … 515 516 516 517 unsigned publicLength = resultArray.size(); 517 unsigned vectorLength = std::max(BASE_VECTOR_LEN, publicLength); 518 unsigned vectorLength = 519 Butterfly::optimalContiguousVectorLength(structure, publicLength); 518 520 519 521 UniquedStringImpl* indexUID = vm().propertyNames->index.impl(); … … 650 652 do { 651 653 MatchResult result; 652 Vector<int , 32> ovector;654 Vector<int> ovector; 653 655 // Model which version of match() is called by the main thread. 654 656 if (replace.isEmpty() && regExp->global()) { -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r204912 r205462 77 77 macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \ 78 78 macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \ 79 macro(MarkedAllocator_freeListHead, MarkedAllocator::offsetOfFreeListHead()) \80 79 macro(RegExpConstructor_cachedResult_lastRegExp, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfLastRegExp()) \ 81 80 macro(RegExpConstructor_cachedResult_lastInput, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfLastInput()) \ … … 110 109 macro(JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, 0, sizeof(WriteBarrier<JSString>)) \ 111 110 macro(JSRopeString_fibers, JSRopeString::offsetOfFibers(), sizeof(WriteBarrier<JSString>)) \ 112 macro(MarkedSpace_Subspace_impreciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, impreciseAllocators), sizeof(MarkedAllocator)) \ 113 macro(MarkedSpace_Subspace_preciseAllocators, OBJECT_OFFSETOF(MarkedSpace::Subspace, preciseAllocators), sizeof(MarkedAllocator)) \ 111 macro(MarkedSpace_Subspace_allocatorForSizeStep, OBJECT_OFFSETOF(MarkedSpace::Subspace, allocatorForSizeStep), sizeof(MarkedAllocator*)) \ 114 112 macro(ScopedArguments_overflowStorage, ScopedArguments::overflowStorageOffset(), sizeof(EncodedJSValue)) \ 115 113 macro(WriteBarrierBuffer_bufferContents, 0, sizeof(JSCell*)) \ -
trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp
r204912 r205462 43 43 #include "FTLThunks.h" 44 44 #include "JITSubGenerator.h" 45 #include "JSCInlines.h" 45 46 #include "LinkBuffer.h" 46 47 #include "PCToCodeOriginMap.h" -
trunk/Source/JavaScriptCore/ftl/FTLJITFinalizer.cpp
r204912 r205462 33 33 #include "FTLState.h" 34 34 #include "FTLThunks.h" 35 #include "JSCInlines.h" 35 36 #include "ProfilerDatabase.h" 36 37 -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r205380 r205462 3816 3816 3817 3817 fastObject = allocateVariableSizedObject<DirectArguments>( 3818 size, structure, m_out.intPtrZero, slowPath);3818 m_out.zeroExtPtr(size), structure, m_out.intPtrZero, slowPath); 3819 3819 } 3820 3820 … … 3916 3916 LValue arrayLength = lowInt32(m_node->child1()); 3917 3917 LBasicBlock loopStart = m_out.newBlock(); 3918 bool shouldLargeArraySizeCreateArrayStorage = false; 3919 LValue array = compileAllocateArrayWithSize(arrayLength, ArrayWithContiguous, shouldLargeArraySizeCreateArrayStorage); 3920 3921 LValue butterfly = m_out.loadPtr(array, m_heaps.JSObject_butterfly); 3918 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); 3919 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous); 3920 ArrayValues arrayValues = allocateUninitializedContiguousJSArray(arrayLength, structure); 3921 LValue array = arrayValues.array; 3922 LValue butterfly = arrayValues.butterfly; 3922 3923 ValueFromBlock startLength = m_out.anchor(arrayLength); 3923 3924 LValue argumentRegion = m_out.add(getArgumentsStart(), m_out.constInt64(sizeof(Register) * m_node->numberOfArgumentsToSkip())); … … 3931 3932 LValue loadedValue = m_out.load64(m_out.baseIndex(m_heaps.variables, argumentRegion, m_out.zeroExtPtr(currentOffset))); 3932 3933 IndexedAbstractHeap& heap = m_heaps.indexedContiguousProperties; 3933 m_out.store (loadedValue, m_out.baseIndex(heap, butterfly, m_out.zeroExtPtr(currentOffset)), Output::Store64);3934 m_out.store64(loadedValue, m_out.baseIndex(heap, butterfly, m_out.zeroExtPtr(currentOffset))); 3934 3935 m_out.branch(m_out.equal(currentOffset, m_out.constInt32(0)), unsure(continuation), unsure(loopStart)); 3935 3936 … … 3988 3989 unsigned numElements = m_node->numChildren(); 3989 3990 3990 ArrayValues arrayValues = allocateJSArray(structure, numElements); 3991 ArrayValues arrayValues = 3992 allocateUninitializedContiguousJSArray(m_out.constInt32(numElements), structure); 3991 3993 3992 3994 for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex) { … … 4064 4066 unsigned numElements = m_node->numConstants(); 4065 4067 4066 ArrayValues arrayValues = allocateJSArray(structure, numElements); 4068 ArrayValues arrayValues = 4069 allocateUninitializedContiguousJSArray(m_out.constInt32(numElements), structure); 4067 4070 4068 4071 JSValue* data = codeBlock()->constantBuffer(m_node->startConstant()); … … 4090 4093 } 4091 4094 4092 LValue compileAllocateArrayWithSize(LValue publicLength, IndexingType indexingType, bool shouldLargeArraySizeCreateArrayStorage = true)4093 {4094 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);4095 Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType);4096 ASSERT(4097 hasUndecided(structure->indexingType())4098 || hasInt32(structure->indexingType())4099 || hasDouble(structure->indexingType())4100 || hasContiguous(structure->indexingType()));4101 4102 LBasicBlock fastCase = m_out.newBlock();4103 LBasicBlock largeCase = shouldLargeArraySizeCreateArrayStorage ? m_out.newBlock() : nullptr;4104 LBasicBlock failCase = m_out.newBlock();4105 LBasicBlock continuation = m_out.newBlock();4106 LBasicBlock lastNext = nullptr;4107 if (shouldLargeArraySizeCreateArrayStorage) {4108 m_out.branch(4109 m_out.aboveOrEqual(publicLength, m_out.constInt32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)),4110 rarely(largeCase), usually(fastCase));4111 lastNext = m_out.appendTo(fastCase, largeCase);4112 }4113 4114 4115 // We don't round up to BASE_VECTOR_LEN for new Array(blah).4116 LValue vectorLength = publicLength;4117 4118 LValue payloadSize =4119 m_out.shl(m_out.zeroExt(vectorLength, pointerType()), m_out.constIntPtr(3));4120 4121 LValue butterflySize = m_out.add(4122 payloadSize, m_out.constIntPtr(sizeof(IndexingHeader)));4123 4124 LValue endOfStorage = allocateBasicStorageAndGetEnd(butterflySize, failCase);4125 4126 LValue butterfly = m_out.sub(endOfStorage, payloadSize);4127 4128 LValue object = allocateObject<JSArray>(structure, butterfly, failCase);4129 4130 m_out.store32(publicLength, butterfly, m_heaps.Butterfly_publicLength);4131 m_out.store32(vectorLength, butterfly, m_heaps.Butterfly_vectorLength);4132 4133 initializeArrayElements(indexingType, vectorLength, butterfly);4134 4135 ValueFromBlock fastResult = m_out.anchor(object);4136 m_out.jump(continuation);4137 4138 LValue structureValue;4139 if (shouldLargeArraySizeCreateArrayStorage) {4140 LBasicBlock slowCase = m_out.newBlock();4141 4142 m_out.appendTo(largeCase, failCase);4143 ValueFromBlock largeStructure = m_out.anchor(m_out.constIntPtr(4144 globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)));4145 m_out.jump(slowCase);4146 4147 m_out.appendTo(failCase, slowCase);4148 ValueFromBlock failStructure = m_out.anchor(m_out.constIntPtr(structure));4149 m_out.jump(slowCase);4150 4151 m_out.appendTo(slowCase, continuation);4152 structureValue = m_out.phi(4153 pointerType(), largeStructure, failStructure);4154 } else {4155 ASSERT(!lastNext);4156 lastNext = m_out.appendTo(failCase, continuation);4157 structureValue = m_out.constIntPtr(structure);4158 }4159 4160 LValue slowResultValue = lazySlowPath(4161 [=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {4162 return createLazyCallGenerator(4163 operationNewArrayWithSize, locations[0].directGPR(),4164 locations[1].directGPR(), locations[2].directGPR());4165 },4166 structureValue, publicLength);4167 ValueFromBlock slowResult = m_out.anchor(slowResultValue);4168 m_out.jump(continuation);4169 4170 m_out.appendTo(continuation, lastNext);4171 return m_out.phi(pointerType(), fastResult, slowResult);4172 }4173 4174 4095 void compileNewArrayWithSize() 4175 4096 { … … 4181 4102 4182 4103 if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(m_node->indexingType())) { 4183 setJSValue(compileAllocateArrayWithSize(publicLength, m_node->indexingType())); 4104 setJSValue( 4105 allocateJSArray( 4106 publicLength, 4107 globalObject->arrayStructureForIndexingTypeDuringAllocation( 4108 m_node->indexingType())).array); 4184 4109 return; 4185 4110 } … … 4190 4115 globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), 4191 4116 m_out.constIntPtr(structure)); 4192 setJSValue(vmCall(Int64, m_out.operation(operationNewArrayWithSize), m_callFrame, structureValue, publicLength ));4117 setJSValue(vmCall(Int64, m_out.operation(operationNewArrayWithSize), m_callFrame, structureValue, publicLength, m_out.intPtrZero)); 4193 4118 } 4194 4119 … … 4450 4375 LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath); 4451 4376 4452 MarkedAllocator &allocator =4377 MarkedAllocator* allocator = 4453 4378 vm().heap.allocatorForObjectWithDestructor(sizeof(JSRopeString)); 4379 DFG_ASSERT(m_graph, m_node, allocator); 4454 4380 4455 4381 LValue result = allocateCell( 4456 m_out.constIntPtr(&allocator), 4457 vm().stringStructure.get(), 4458 slowPath); 4382 m_out.constIntPtr(allocator), vm().stringStructure.get(), slowPath); 4459 4383 4460 4384 m_out.storePtr(m_out.intPtrZero, result, m_heaps.JSString_value); … … 7005 6929 if (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType())) { 7006 6930 size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity()); 7007 MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize); 6931 MarkedAllocator* cellAllocator = vm().heap.allocatorForObjectWithoutDestructor(allocationSize); 6932 DFG_ASSERT(m_graph, m_node, cellAllocator); 7008 6933 7009 6934 bool hasIndexingHeader = hasIndexedProperties(structure->indexingType()); … … 7030 6955 m_out.mul(m_out.zeroExtPtr(vectorLength), m_out.intPtrEight); 7031 6956 } 7032 6957 7033 6958 LValue butterflySize = m_out.add( 7034 6959 m_out.constIntPtr( … … 7041 6966 LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath); 7042 6967 7043 LValue endOfStorage = allocateBasicStorageAndGetEnd(butterflySize, slowPath); 6968 ValueFromBlock noButterfly = m_out.anchor(m_out.intPtrZero); 6969 6970 LValue startOfStorage = allocateHeapCell( 6971 allocatorForSize(vm().heap.subspaceForAuxiliaryData(), butterflySize, slowPath), 6972 slowPath); 7044 6973 7045 6974 LValue fastButterflyValue = m_out.add( 7046 m_out.sub(endOfStorage, indexingPayloadSizeInBytes), 7047 m_out.constIntPtr(sizeof(IndexingHeader) - indexingHeaderSize)); 6975 startOfStorage, 6976 m_out.constIntPtr( 6977 structure->outOfLineCapacity() * sizeof(JSValue) + sizeof(IndexingHeader))); 6978 6979 ValueFromBlock haveButterfly = m_out.anchor(fastButterflyValue); 7048 6980 7049 6981 m_out.store32(vectorLength, fastButterflyValue, m_heaps.Butterfly_vectorLength); 7050 6982 7051 6983 LValue fastObjectValue = allocateObject( 7052 m_out.constIntPtr( allocator), structure, fastButterflyValue, slowPath);6984 m_out.constIntPtr(cellAllocator), structure, fastButterflyValue, slowPath); 7053 6985 7054 6986 ValueFromBlock fastObject = m_out.anchor(fastObjectValue); … … 7057 6989 7058 6990 m_out.appendTo(slowPath, continuation); 6991 6992 LValue butterflyValue = m_out.phi(pointerType(), noButterfly, haveButterfly); 7059 6993 7060 6994 LValue slowObjectValue; … … 7065 6999 operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength, 7066 7000 locations[0].directGPR(), CCallHelpers::TrustedImmPtr(structure), 7067 locations[1].directGPR() );7001 locations[1].directGPR(), locations[2].directGPR()); 7068 7002 }, 7069 vectorLength );7003 vectorLength, butterflyValue); 7070 7004 } else { 7071 7005 slowObjectValue = lazySlowPath( … … 7073 7007 return createLazyCallGenerator( 7074 7008 operationNewObjectWithButterfly, locations[0].directGPR(), 7075 CCallHelpers::TrustedImmPtr(structure)); 7076 }); 7009 CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR()); 7010 }, 7011 butterflyValue); 7077 7012 } 7078 7013 ValueFromBlock slowObject = m_out.anchor(slowObjectValue); … … 7089 7024 m_out.store32(publicLength, butterfly, m_heaps.Butterfly_publicLength); 7090 7025 7091 initializeArrayElements(structure->indexingType(), vectorLength, butterfly);7026 initializeArrayElements(structure->indexingType(), m_out.int32Zero, vectorLength, butterfly); 7092 7027 7093 7028 HashMap<int32_t, LValue, DefaultHash<int32_t>::Hash, WTF::UnsignedWithZeroKeyHashTraits<int32_t>> indexMap; … … 7834 7769 } 7835 7770 7836 void initializeArrayElements(IndexingType indexingType, LValue vectorLength, LValue butterfly) 7837 { 7838 if (!hasDouble(indexingType)) { 7839 // The GC already initialized everything to JSValue() for us. 7840 return; 7771 void initializeArrayElements(IndexingType indexingType, LValue begin, LValue end, LValue butterfly) 7772 { 7773 if (hasUndecided(indexingType)) 7774 return; 7775 7776 if (begin == end) 7777 return; 7778 7779 IndexedAbstractHeap* heap = m_heaps.forIndexingType(indexingType); 7780 DFG_ASSERT(m_graph, m_node, heap); 7781 7782 LValue hole; 7783 if (hasDouble(indexingType)) 7784 hole = m_out.constInt64(bitwise_cast<int64_t>(PNaN)); 7785 else 7786 hole = m_out.constInt64(JSValue::encode(JSValue())); 7787 7788 const uint64_t unrollingLimit = 10; 7789 if (begin->hasInt() && end->hasInt()) { 7790 uint64_t beginConst = static_cast<uint64_t>(begin->asInt()); 7791 uint64_t endConst = static_cast<uint64_t>(end->asInt()); 7792 7793 if (endConst - beginConst <= unrollingLimit) { 7794 for (uint64_t i = beginConst; i < endConst; ++i) 7795 m_out.store64(hole, butterfly, heap->at(i)); 7796 return; 7797 } 7841 7798 } 7842 7799 … … 7845 7802 LBasicBlock initDone = m_out.newBlock(); 7846 7803 7847 ValueFromBlock originalIndex = m_out.anchor( vectorLength);7804 ValueFromBlock originalIndex = m_out.anchor(end); 7848 7805 ValueFromBlock originalPointer = m_out.anchor(butterfly); 7849 m_out.branch( 7850 m_out.notZero32(vectorLength), unsure(initLoop), unsure(initDone)); 7806 m_out.branch(m_out.notEqual(end, begin), unsure(initLoop), unsure(initDone)); 7851 7807 7852 7808 LBasicBlock initLastNext = m_out.appendTo(initLoop, initDone); … … 7854 7810 LValue pointer = m_out.phi(pointerType(), originalPointer); 7855 7811 7856 m_out.store64( 7857 m_out.constInt64(bitwise_cast<int64_t>(PNaN)), 7858 TypedPointer(m_heaps.indexedDoubleProperties.atAnyIndex(), pointer)); 7812 m_out.store64(hole, TypedPointer(heap->atAnyIndex(), pointer)); 7859 7813 7860 7814 LValue nextIndex = m_out.sub(index, m_out.int32One); … … 7862 7816 m_out.addIncomingToPhi(pointer, m_out.anchor(m_out.add(pointer, m_out.intPtrEight))); 7863 7817 m_out.branch( 7864 m_out.not Zero32(nextIndex), unsure(initLoop), unsure(initDone));7818 m_out.notEqual(nextIndex, begin), unsure(initLoop), unsure(initDone)); 7865 7819 7866 7820 m_out.appendTo(initDone, initLastNext); … … 7917 7871 7918 7872 LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath); 7919 7920 LValue endOfStorage = allocateBasicStorageAndGetEnd(7921 m_out.constIntPtr(sizeInValues * sizeof(JSValue)), slowPath);7922 7873 7874 size_t sizeInBytes = sizeInValues * sizeof(JSValue); 7875 MarkedAllocator* allocator = vm().heap.allocatorForAuxiliaryData(sizeInBytes); 7876 LValue startOfStorage = allocateHeapCell(m_out.constIntPtr(allocator), slowPath); 7923 7877 ValueFromBlock fastButterfly = m_out.anchor( 7924 m_out.add(m_out.constIntPtr(sizeof(IndexingHeader)), endOfStorage)); 7925 7878 m_out.add(m_out.constIntPtr(sizeInBytes + sizeof(IndexingHeader)), startOfStorage)); 7926 7879 m_out.jump(continuation); 7927 7880 … … 8488 8441 } 8489 8442 8490 LValue allocateCell(LValue allocator, LBasicBlock slowPath) 8491 { 8492 LBasicBlock success = m_out.newBlock(); 8493 8494 LValue result; 8495 LValue condition; 8496 if (Options::forceGCSlowPaths()) { 8497 result = m_out.intPtrZero; 8498 condition = m_out.booleanFalse; 8499 } else { 8500 result = m_out.loadPtr( 8501 allocator, m_heaps.MarkedAllocator_freeListHead); 8502 condition = m_out.notNull(result); 8503 } 8504 m_out.branch(condition, usually(success), rarely(slowPath)); 8505 8506 m_out.appendTo(success); 8507 8508 m_out.storePtr( 8509 m_out.loadPtr(result, m_heaps.JSCell_freeListNext), 8510 allocator, m_heaps.MarkedAllocator_freeListHead); 8511 8512 return result; 8443 LValue allocateHeapCell(LValue allocator, LBasicBlock slowPath) 8444 { 8445 MarkedAllocator* actualAllocator = nullptr; 8446 if (allocator->hasIntPtr()) 8447 actualAllocator = bitwise_cast<MarkedAllocator*>(allocator->asIntPtr()); 8448 8449 if (!actualAllocator) { 8450 // This means that either we know that the allocator is null or we don't know what the 8451 // allocator is. In either case, we need the null check. 8452 LBasicBlock haveAllocator = m_out.newBlock(); 8453 LBasicBlock lastNext = m_out.insertNewBlocksBefore(haveAllocator); 8454 m_out.branch(allocator, usually(haveAllocator), rarely(slowPath)); 8455 m_out.appendTo(haveAllocator, lastNext); 8456 } 8457 8458 LBasicBlock continuation = m_out.newBlock(); 8459 8460 LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation); 8461 8462 PatchpointValue* patchpoint = m_out.patchpoint(pointerType()); 8463 patchpoint->effects.terminal = true; 8464 patchpoint->appendSomeRegister(allocator); 8465 patchpoint->numGPScratchRegisters++; 8466 patchpoint->resultConstraint = ValueRep::SomeEarlyRegister; 8467 8468 m_out.appendSuccessor(usually(continuation)); 8469 m_out.appendSuccessor(rarely(slowPath)); 8470 8471 patchpoint->setGenerator( 8472 [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { 8473 CCallHelpers::JumpList jumpToSlowPath; 8474 8475 // We use a patchpoint to emit the allocation path because whenever we mess with 8476 // allocation paths, we already reason about them at the machine code level. We know 8477 // exactly what instruction sequence we want. We're confident that no compiler 8478 // optimization could make this code better. So, it's best to have the code in 8479 // AssemblyHelpers::emitAllocate(). That way, the same optimized path is shared by 8480 // all of the compiler tiers. 8481 jit.emitAllocateWithNonNullAllocator( 8482 params[0].gpr(), actualAllocator, params[1].gpr(), params.gpScratch(0), 8483 jumpToSlowPath); 8484 8485 CCallHelpers::Jump jumpToSuccess; 8486 if (!params.fallsThroughToSuccessor(0)) 8487 jumpToSuccess = jit.jump(); 8488 8489 Vector<Box<CCallHelpers::Label>> labels = params.successorLabels(); 8490 8491 params.addLatePath( 8492 [=] (CCallHelpers& jit) { 8493 jumpToSlowPath.linkTo(*labels[1], &jit); 8494 if (jumpToSuccess.isSet()) 8495 jumpToSuccess.linkTo(*labels[0], &jit); 8496 }); 8497 }); 8498 8499 m_out.appendTo(continuation, lastNext); 8500 return patchpoint; 8513 8501 } 8514 8502 … … 8523 8511 LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath) 8524 8512 { 8525 LValue result = allocate Cell(allocator, slowPath);8513 LValue result = allocateHeapCell(allocator, slowPath); 8526 8514 storeStructure(result, structure); 8527 8515 return result; … … 8540 8528 size_t size, Structure* structure, LValue butterfly, LBasicBlock slowPath) 8541 8529 { 8542 MarkedAllocator* allocator = &vm().heap.allocatorForObjectOfType<ClassType>(size);8530 MarkedAllocator* allocator = vm().heap.allocatorForObjectOfType<ClassType>(size); 8543 8531 return allocateObject(m_out.constIntPtr(allocator), structure, butterfly, slowPath); 8544 8532 } … … 8549 8537 return allocateObject<ClassType>( 8550 8538 ClassType::allocationSize(0), structure, butterfly, slowPath); 8539 } 8540 8541 LValue allocatorForSize(LValue subspace, LValue size, LBasicBlock slowPath) 8542 { 8543 static_assert(!(MarkedSpace::sizeStep & (MarkedSpace::sizeStep - 1)), "MarkedSpace::sizeStep must be a power of two."); 8544 8545 // Try to do some constant-folding here. 8546 if (subspace->hasIntPtr() && size->hasIntPtr()) { 8547 MarkedSpace::Subspace* actualSubspace = bitwise_cast<MarkedSpace::Subspace*>(subspace->asIntPtr()); 8548 size_t actualSize = size->asIntPtr(); 8549 8550 MarkedAllocator* actualAllocator = MarkedSpace::allocatorFor(*actualSubspace, actualSize); 8551 if (!actualAllocator) { 8552 LBasicBlock continuation = m_out.newBlock(); 8553 LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation); 8554 m_out.jump(slowPath); 8555 m_out.appendTo(continuation, lastNext); 8556 return m_out.intPtrZero; 8557 } 8558 8559 return m_out.constIntPtr(actualAllocator); 8560 } 8561 8562 unsigned stepShift = getLSBSet(MarkedSpace::sizeStep); 8563 8564 LBasicBlock continuation = m_out.newBlock(); 8565 8566 LBasicBlock lastNext = m_out.insertNewBlocksBefore(continuation); 8567 8568 LValue sizeClassIndex = m_out.lShr( 8569 m_out.add(size, m_out.constIntPtr(MarkedSpace::sizeStep - 1)), 8570 m_out.constInt32(stepShift)); 8571 8572 m_out.branch( 8573 m_out.above(sizeClassIndex, m_out.constIntPtr(MarkedSpace::largeCutoff >> stepShift)), 8574 rarely(slowPath), usually(continuation)); 8575 8576 m_out.appendTo(continuation, lastNext); 8577 8578 return m_out.loadPtr( 8579 m_out.baseIndex( 8580 m_heaps.MarkedSpace_Subspace_allocatorForSizeStep, 8581 subspace, m_out.sub(sizeClassIndex, m_out.intPtrOne))); 8582 } 8583 8584 LValue allocatorForSize(MarkedSpace::Subspace& subspace, LValue size, LBasicBlock slowPath) 8585 { 8586 return allocatorForSize(m_out.constIntPtr(&subspace), size, slowPath); 8551 8587 } 8552 8588 … … 8555 8591 LValue size, Structure* structure, LValue butterfly, LBasicBlock slowPath) 8556 8592 { 8557 static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two."); 8558 static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two."); 8559 8560 LValue subspace = m_out.constIntPtr(&vm().heap.subspaceForObjectOfType<ClassType>()); 8561 8562 LBasicBlock smallCaseBlock = m_out.newBlock(); 8563 LBasicBlock largeOrOversizeCaseBlock = m_out.newBlock(); 8564 LBasicBlock largeCaseBlock = m_out.newBlock(); 8565 LBasicBlock continuation = m_out.newBlock(); 8566 8567 LValue uproundedSize = m_out.add(size, m_out.constInt32(MarkedSpace::preciseStep - 1)); 8568 LValue isSmall = m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::preciseCutoff)); 8569 m_out.branch(isSmall, unsure(smallCaseBlock), unsure(largeOrOversizeCaseBlock)); 8570 8571 LBasicBlock lastNext = m_out.appendTo(smallCaseBlock, largeOrOversizeCaseBlock); 8572 TypedPointer address = m_out.baseIndex( 8573 m_heaps.MarkedSpace_Subspace_preciseAllocators, subspace, 8574 m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::preciseStep))))); 8575 ValueFromBlock smallAllocator = m_out.anchor(address.value()); 8576 m_out.jump(continuation); 8577 8578 m_out.appendTo(largeOrOversizeCaseBlock, largeCaseBlock); 8579 m_out.branch( 8580 m_out.below(uproundedSize, m_out.constInt32(MarkedSpace::impreciseCutoff)), 8581 usually(largeCaseBlock), rarely(slowPath)); 8582 8583 m_out.appendTo(largeCaseBlock, continuation); 8584 address = m_out.baseIndex( 8585 m_heaps.MarkedSpace_Subspace_impreciseAllocators, subspace, 8586 m_out.zeroExtPtr(m_out.lShr(uproundedSize, m_out.constInt32(getLSBSet(MarkedSpace::impreciseStep))))); 8587 ValueFromBlock largeAllocator = m_out.anchor(address.value()); 8588 m_out.jump(continuation); 8589 8590 m_out.appendTo(continuation, lastNext); 8591 LValue allocator = m_out.phi(pointerType(), smallAllocator, largeAllocator); 8592 8593 LValue allocator = allocatorForSize( 8594 vm().heap.subspaceForObjectOfType<ClassType>(), size, slowPath); 8593 8595 return allocateObject(allocator, structure, butterfly, slowPath); 8594 8596 } … … 8623 8625 { 8624 8626 size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity()); 8625 MarkedAllocator* allocator = &vm().heap.allocatorForObjectWithoutDestructor(allocationSize); 8627 MarkedAllocator* allocator = vm().heap.allocatorForObjectWithoutDestructor(allocationSize); 8628 8629 // FIXME: If the allocator is null, we could simply emit a normal C call to the allocator 8630 // instead of putting it on the slow path. 8631 // https://bugs.webkit.org/show_bug.cgi?id=161062 8626 8632 8627 8633 LBasicBlock slowPath = m_out.newBlock(); … … 8666 8672 LValue butterfly; 8667 8673 }; 8668 ArrayValues allocateJSArray( 8669 Structure* structure, unsigned numElements, LBasicBlock slowPath) 8670 { 8674 8675 ArrayValues allocateJSArray(LValue publicLength, Structure* structure, bool shouldInitializeElements = true, bool shouldLargeArraySizeCreateArrayStorage = true) 8676 { 8677 JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); 8678 IndexingType indexingType = structure->indexingType(); 8671 8679 ASSERT( 8672 hasUndecided(structure->indexingType()) 8673 || hasInt32(structure->indexingType()) 8674 || hasDouble(structure->indexingType()) 8675 || hasContiguous(structure->indexingType())); 8676 8677 unsigned vectorLength = std::max(BASE_VECTOR_LEN, numElements); 8678 8679 LValue endOfStorage = allocateBasicStorageAndGetEnd( 8680 m_out.constIntPtr(sizeof(JSValue) * vectorLength + sizeof(IndexingHeader)), 8681 slowPath); 8682 8683 LValue butterfly = m_out.sub( 8684 endOfStorage, m_out.constIntPtr(sizeof(JSValue) * vectorLength)); 8685 8686 LValue object = allocateObject<JSArray>( 8687 structure, butterfly, slowPath); 8688 8689 m_out.store32(m_out.constInt32(numElements), butterfly, m_heaps.Butterfly_publicLength); 8690 m_out.store32(m_out.constInt32(vectorLength), butterfly, m_heaps.Butterfly_vectorLength); 8691 8692 if (hasDouble(structure->indexingType())) { 8693 for (unsigned i = numElements; i < vectorLength; ++i) { 8694 m_out.store64( 8695 m_out.constInt64(bitwise_cast<int64_t>(PNaN)), 8696 butterfly, m_heaps.indexedDoubleProperties[i]); 8680 hasUndecided(indexingType) 8681 || hasInt32(indexingType) 8682 || hasDouble(indexingType) 8683 || hasContiguous(indexingType)); 8684 8685 LBasicBlock fastCase = m_out.newBlock(); 8686 LBasicBlock largeCase = m_out.newBlock(); 8687 LBasicBlock failCase = m_out.newBlock(); 8688 LBasicBlock continuation = m_out.newBlock(); 8689 LBasicBlock slowCase = m_out.newBlock(); 8690 8691 LBasicBlock lastNext = m_out.insertNewBlocksBefore(fastCase); 8692 8693 ValueFromBlock noButterfly = m_out.anchor(m_out.intPtrZero); 8694 8695 LValue predicate; 8696 if (shouldLargeArraySizeCreateArrayStorage) 8697 predicate = m_out.aboveOrEqual(publicLength, m_out.constInt32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)); 8698 else 8699 predicate = m_out.booleanFalse; 8700 8701 m_out.branch(predicate, rarely(largeCase), usually(fastCase)); 8702 8703 m_out.appendTo(fastCase, largeCase); 8704 8705 LValue vectorLength = nullptr; 8706 if (publicLength->hasInt32()) { 8707 unsigned publicLengthConst = static_cast<unsigned>(publicLength->asInt32()); 8708 if (publicLengthConst <= MAX_STORAGE_VECTOR_LENGTH) { 8709 vectorLength = m_out.constInt32( 8710 Butterfly::optimalContiguousVectorLength( 8711 structure->outOfLineCapacity(), publicLengthConst)); 8697 8712 } 8698 8713 } 8699 8714 8700 return ArrayValues(object, butterfly); 8701 } 8702 8703 ArrayValues allocateJSArray(Structure* structure, unsigned numElements) 8704 { 8705 LBasicBlock slowPath = m_out.newBlock(); 8706 LBasicBlock continuation = m_out.newBlock(); 8707 8708 LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath); 8709 8710 ArrayValues fastValues = allocateJSArray(structure, numElements, slowPath); 8711 ValueFromBlock fastArray = m_out.anchor(fastValues.array); 8712 ValueFromBlock fastButterfly = m_out.anchor(fastValues.butterfly); 8713 8715 if (!vectorLength) { 8716 // We don't compute the optimal vector length for new Array(blah) where blah is not 8717 // statically known, since the compute effort of doing it here is probably not worth it. 8718 vectorLength = publicLength; 8719 } 8720 8721 LValue payloadSize = 8722 m_out.shl(m_out.zeroExt(vectorLength, pointerType()), m_out.constIntPtr(3)); 8723 8724 LValue butterflySize = m_out.add( 8725 payloadSize, m_out.constIntPtr(sizeof(IndexingHeader))); 8726 8727 LValue allocator = allocatorForSize( 8728 vm().heap.subspaceForAuxiliaryData(), butterflySize, failCase); 8729 LValue startOfStorage = allocateHeapCell(allocator, failCase); 8730 8731 LValue butterfly = m_out.add(startOfStorage, m_out.constIntPtr(sizeof(IndexingHeader))); 8732 8733 m_out.store32(publicLength, butterfly, m_heaps.Butterfly_publicLength); 8734 m_out.store32(vectorLength, butterfly, m_heaps.Butterfly_vectorLength); 8735 8736 initializeArrayElements( 8737 indexingType, 8738 shouldInitializeElements ? m_out.int32Zero : publicLength, vectorLength, 8739 butterfly); 8740 8741 ValueFromBlock haveButterfly = m_out.anchor(butterfly); 8742 8743 LValue object = allocateObject<JSArray>(structure, butterfly, failCase); 8744 8745 ValueFromBlock fastResult = m_out.anchor(object); 8746 ValueFromBlock fastButterfly = m_out.anchor(butterfly); 8714 8747 m_out.jump(continuation); 8715 8748 8716 m_out.appendTo(slowPath, continuation); 8717 8718 LValue slowArrayValue = lazySlowPath( 8749 m_out.appendTo(largeCase, failCase); 8750 ValueFromBlock largeStructure = m_out.anchor( 8751 m_out.constIntPtr( 8752 globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage))); 8753 m_out.jump(slowCase); 8754 8755 m_out.appendTo(failCase, slowCase); 8756 ValueFromBlock failStructure = m_out.anchor(m_out.constIntPtr(structure)); 8757 m_out.jump(slowCase); 8758 8759 m_out.appendTo(slowCase, continuation); 8760 LValue structureValue = m_out.phi(pointerType(), largeStructure, failStructure); 8761 LValue butterflyValue = m_out.phi(pointerType(), noButterfly, haveButterfly); 8762 8763 LValue slowResultValue = lazySlowPath( 8719 8764 [=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> { 8720 8765 return createLazyCallGenerator( 8721 8766 operationNewArrayWithSize, locations[0].directGPR(), 8722 CCallHelpers::TrustedImmPtr(structure), CCallHelpers::TrustedImm32(numElements)); 8723 }); 8724 ValueFromBlock slowArray = m_out.anchor(slowArrayValue); 8767 locations[1].directGPR(), locations[2].directGPR(), locations[3].directGPR()); 8768 }, 8769 structureValue, publicLength, butterflyValue); 8770 ValueFromBlock slowResult = m_out.anchor(slowResultValue); 8725 8771 ValueFromBlock slowButterfly = m_out.anchor( 8726 m_out.loadPtr(slowArrayValue, m_heaps.JSObject_butterfly)); 8727 8772 m_out.loadPtr(slowResultValue, m_heaps.JSObject_butterfly)); 8728 8773 m_out.jump(continuation); 8729 8774 8730 8775 m_out.appendTo(continuation, lastNext); 8731 8732 8776 return ArrayValues( 8733 m_out.phi(pointerType(), fast Array, slowArray),8777 m_out.phi(pointerType(), fastResult, slowResult), 8734 8778 m_out.phi(pointerType(), fastButterfly, slowButterfly)); 8779 } 8780 8781 ArrayValues allocateUninitializedContiguousJSArray(LValue publicLength, Structure* structure) 8782 { 8783 bool shouldInitializeElements = false; 8784 bool shouldLargeArraySizeCreateArrayStorage = false; 8785 return allocateJSArray( 8786 publicLength, structure, shouldInitializeElements, 8787 shouldLargeArraySizeCreateArrayStorage); 8735 8788 } 8736 8789 -
trunk/Source/JavaScriptCore/ftl/FTLOutput.cpp
r204912 r205462 101 101 LValue Output::constBool(bool value) 102 102 { 103 if (value) 104 return booleanTrue; 105 return booleanFalse; 106 } 107 108 LValue Output::constInt32(int32_t value) 109 { 103 110 return m_block->appendNew<B3::Const32Value>(m_proc, origin(), value); 104 111 } 105 112 106 LValue Output::constInt32(int32_t value)107 {108 return m_block->appendNew<B3::Const32Value>(m_proc, origin(), value);109 }110 111 113 LValue Output::constInt64(int64_t value) 112 114 { … … 126 128 LValue Output::add(LValue left, LValue right) 127 129 { 130 if (Value* result = left->addConstant(m_proc, right)) { 131 m_block->append(result); 132 return result; 133 } 128 134 return m_block->appendNew<B3::Value>(m_proc, B3::Add, origin(), left, right); 129 135 } … … 206 212 LValue Output::shl(LValue left, LValue right) 207 213 { 208 return m_block->appendNew<B3::Value>(m_proc, B3::Shl, origin(), left, castToInt32(right)); 214 right = castToInt32(right); 215 if (Value* result = left->shlConstant(m_proc, right)) { 216 m_block->append(result); 217 return result; 218 } 219 return m_block->appendNew<B3::Value>(m_proc, B3::Shl, origin(), left, right); 209 220 } 210 221 211 222 LValue Output::aShr(LValue left, LValue right) 212 223 { 213 return m_block->appendNew<B3::Value>(m_proc, B3::SShr, origin(), left, castToInt32(right)); 224 right = castToInt32(right); 225 if (Value* result = left->sShrConstant(m_proc, right)) { 226 m_block->append(result); 227 return result; 228 } 229 return m_block->appendNew<B3::Value>(m_proc, B3::SShr, origin(), left, right); 214 230 } 215 231 216 232 LValue Output::lShr(LValue left, LValue right) 217 233 { 218 return m_block->appendNew<B3::Value>(m_proc, B3::ZShr, origin(), left, castToInt32(right)); 234 right = castToInt32(right); 235 if (Value* result = left->zShrConstant(m_proc, right)) { 236 m_block->append(result); 237 return result; 238 } 239 return m_block->appendNew<B3::Value>(m_proc, B3::ZShr, origin(), left, right); 219 240 } 220 241 … … 344 365 if (value->type() == type) 345 366 return value; 367 if (value->hasInt32()) 368 return m_block->appendIntConstant(m_proc, origin(), Int64, static_cast<uint64_t>(static_cast<uint32_t>(value->asInt32()))); 346 369 return m_block->appendNew<B3::Value>(m_proc, B3::ZExt32, origin(), value); 347 370 } … … 359 382 LValue Output::castToInt32(LValue value) 360 383 { 361 return value->type() == B3::Int32 ? value : 362 m_block->appendNew<B3::Value>(m_proc, B3::Trunc, origin(), value); 384 if (value->type() == Int32) 385 return value; 386 if (value->hasInt64()) 387 return constInt32(static_cast<int32_t>(value->asInt64())); 388 return m_block->appendNew<B3::Value>(m_proc, B3::Trunc, origin(), value); 363 389 } 364 390 … … 454 480 LValue Output::equal(LValue left, LValue right) 455 481 { 482 TriState result = left->equalConstant(right); 483 if (result != MixedTriState) 484 return constBool(result == TrueTriState); 456 485 return m_block->appendNew<B3::Value>(m_proc, B3::Equal, origin(), left, right); 457 486 } … … 459 488 LValue Output::notEqual(LValue left, LValue right) 460 489 { 490 TriState result = left->notEqualConstant(right); 491 if (result != MixedTriState) 492 return constBool(result == TrueTriState); 461 493 return m_block->appendNew<B3::Value>(m_proc, B3::NotEqual, origin(), left, right); 462 494 } … … 464 496 LValue Output::above(LValue left, LValue right) 465 497 { 498 TriState result = left->aboveConstant(right); 499 if (result != MixedTriState) 500 return constBool(result == TrueTriState); 466 501 return m_block->appendNew<B3::Value>(m_proc, B3::Above, origin(), left, right); 467 502 } … … 469 504 LValue Output::aboveOrEqual(LValue left, LValue right) 470 505 { 506 TriState result = left->aboveEqualConstant(right); 507 if (result != MixedTriState) 508 return constBool(result == TrueTriState); 471 509 return m_block->appendNew<B3::Value>(m_proc, B3::AboveEqual, origin(), left, right); 472 510 } … … 474 512 LValue Output::below(LValue left, LValue right) 475 513 { 514 TriState result = left->belowConstant(right); 515 if (result != MixedTriState) 516 return constBool(result == TrueTriState); 476 517 return m_block->appendNew<B3::Value>(m_proc, B3::Below, origin(), left, right); 477 518 } … … 479 520 LValue Output::belowOrEqual(LValue left, LValue right) 480 521 { 522 TriState result = left->belowEqualConstant(right); 523 if (result != MixedTriState) 524 return constBool(result == TrueTriState); 481 525 return m_block->appendNew<B3::Value>(m_proc, B3::BelowEqual, origin(), left, right); 482 526 } … … 484 528 LValue Output::greaterThan(LValue left, LValue right) 485 529 { 530 TriState result = left->greaterThanConstant(right); 531 if (result != MixedTriState) 532 return constBool(result == TrueTriState); 486 533 return m_block->appendNew<B3::Value>(m_proc, B3::GreaterThan, origin(), left, right); 487 534 } … … 489 536 LValue Output::greaterThanOrEqual(LValue left, LValue right) 490 537 { 538 TriState result = left->greaterEqualConstant(right); 539 if (result != MixedTriState) 540 return constBool(result == TrueTriState); 491 541 return m_block->appendNew<B3::Value>(m_proc, B3::GreaterEqual, origin(), left, right); 492 542 } … … 494 544 LValue Output::lessThan(LValue left, LValue right) 495 545 { 546 TriState result = left->lessThanConstant(right); 547 if (result != MixedTriState) 548 return constBool(result == TrueTriState); 496 549 return m_block->appendNew<B3::Value>(m_proc, B3::LessThan, origin(), left, right); 497 550 } … … 499 552 LValue Output::lessThanOrEqual(LValue left, LValue right) 500 553 { 554 TriState result = left->lessEqualConstant(right); 555 if (result != MixedTriState) 556 return constBool(result == TrueTriState); 501 557 return m_block->appendNew<B3::Value>(m_proc, B3::LessEqual, origin(), left, right); 502 558 } … … 584 640 LValue Output::select(LValue value, LValue taken, LValue notTaken) 585 641 { 642 if (value->hasInt32()) { 643 if (value->asInt32()) 644 return taken; 645 else 646 return notTaken; 647 } 586 648 return m_block->appendNew<B3::Value>(m_proc, B3::Select, origin(), value, taken, notTaken); 587 649 } … … 620 682 { 621 683 m_block->appendNewControlValue(m_proc, B3::Oops, origin()); 684 } 685 686 void Output::appendSuccessor(WeightedTarget target) 687 { 688 m_block->appendSuccessor(target.frequentedBlock()); 622 689 } 623 690 … … 742 809 void Output::addIncomingToPhi(LValue phi, ValueFromBlock value) 743 810 { 744 value.value()->as<B3::UpsilonValue>()->setPhi(phi); 811 if (value) 812 value.value()->as<B3::UpsilonValue>()->setPhi(phi); 745 813 } 746 814 -
trunk/Source/JavaScriptCore/ftl/FTLOutput.h
r204912 r205462 399 399 400 400 void unreachable(); 401 402 void appendSuccessor(WeightedTarget); 401 403 402 404 B3::CheckValue* speculate(LValue); -
trunk/Source/JavaScriptCore/ftl/FTLValueFromBlock.h
r204912 r205462 46 46 { 47 47 } 48 49 explicit operator bool() const { return m_value || m_block; } 48 50 49 51 LValue value() const { return m_value; } -
trunk/Source/JavaScriptCore/ftl/FTLWeightedTarget.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 56 56 Weight weight() const { return m_weight; } 57 57 58 B3::FrequentedBlock frequentedBlock() const 59 { 60 return B3::FrequentedBlock(target(), weight().frequencyClass()); 61 } 62 58 63 private: 59 64 LBasicBlock m_target; -
trunk/Source/JavaScriptCore/heap/ConservativeRoots.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2011 Apple Inc. All rights reserved.2 * Copyright (C) 2011, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "CopiedSpaceInlines.h" 33 33 #include "HeapInlines.h" 34 #include "HeapUtil.h" 35 #include "JITStubRoutineSet.h" 34 36 #include "JSCell.h" 35 37 #include "JSObject.h" … … 40 42 namespace JSC { 41 43 42 ConservativeRoots::ConservativeRoots( MarkedBlockSet* blocks, CopiedSpace* copiedSpace)44 ConservativeRoots::ConservativeRoots(Heap& heap) 43 45 : m_roots(m_inlineRoots) 44 46 , m_size(0) 45 47 , m_capacity(inlineCapacity) 46 , m_blocks(blocks) 47 , m_copiedSpace(copiedSpace) 48 , m_heap(heap) 48 49 { 49 50 } … … 52 53 { 53 54 if (m_roots != m_inlineRoots) 54 OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof( JSCell*));55 OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(HeapCell*)); 55 56 } 56 57 … … 58 59 { 59 60 size_t newCapacity = m_capacity == inlineCapacity ? nonInlineCapacity : m_capacity * 2; 60 JSCell** newRoots = static_cast<JSCell**>(OSAllocator::reserveAndCommit(newCapacity * sizeof(JSCell*)));61 memcpy(newRoots, m_roots, m_size * sizeof( JSCell*));61 HeapCell** newRoots = static_cast<HeapCell**>(OSAllocator::reserveAndCommit(newCapacity * sizeof(HeapCell*))); 62 memcpy(newRoots, m_roots, m_size * sizeof(HeapCell*)); 62 63 if (m_roots != m_inlineRoots) 63 OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof( JSCell*));64 OSAllocator::decommitAndRelease(m_roots, m_capacity * sizeof(HeapCell*)); 64 65 m_capacity = newCapacity; 65 66 m_roots = newRoots; … … 67 68 68 69 template<typename MarkHook> 69 inline void ConservativeRoots::genericAddPointer(void* p, TinyBloomFilter filter, MarkHook& markHook)70 inline void ConservativeRoots::genericAddPointer(void* p, int64_t version, TinyBloomFilter filter, MarkHook& markHook) 70 71 { 71 72 markHook.mark(p); 72 73 73 m_ copiedSpace->pinIfNecessary(p);74 m_heap.storageSpace().pinIfNecessary(p); 74 75 75 if (!Heap::isPointerGCObject(filter, *m_blocks, p)) 76 return; 77 78 if (m_size == m_capacity) 79 grow(); 80 81 m_roots[m_size++] = static_cast<JSCell*>(p); 76 HeapUtil::findGCObjectPointersForMarking( 77 m_heap, version, filter, p, 78 [&] (void* p) { 79 if (m_size == m_capacity) 80 grow(); 81 82 m_roots[m_size++] = bitwise_cast<HeapCell*>(p); 83 }); 82 84 } 83 85 … … 95 97 RELEASE_ASSERT(isPointerAligned(end)); 96 98 97 TinyBloomFilter filter = m_blocks->filter(); // Make a local copy of filter to show the compiler it won't alias, and can be register-allocated. 99 TinyBloomFilter filter = m_heap.objectSpace().blocks().filter(); // Make a local copy of filter to show the compiler it won't alias, and can be register-allocated. 100 int64_t version = m_heap.objectSpace().version(); 98 101 for (char** it = static_cast<char**>(begin); it != static_cast<char**>(end); ++it) 99 genericAddPointer(*it, filter, markHook);102 genericAddPointer(*it, version, filter, markHook); 100 103 } 101 104 -
trunk/Source/JavaScriptCore/heap/ConservativeRoots.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved.2 * Copyright (C) 2009, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 33 33 class CodeBlockSet; 34 class HeapCell; 34 35 class JITStubRoutineSet; 35 class JSCell;36 36 37 37 class ConservativeRoots { 38 38 public: 39 ConservativeRoots( MarkedBlockSet*, CopiedSpace*);39 ConservativeRoots(Heap&); 40 40 ~ConservativeRoots(); 41 41 … … 45 45 46 46 size_t size(); 47 JSCell** roots();47 HeapCell** roots(); 48 48 49 49 private: 50 50 static const size_t inlineCapacity = 128; 51 static const size_t nonInlineCapacity = 8192 / sizeof( JSCell*);51 static const size_t nonInlineCapacity = 8192 / sizeof(HeapCell*); 52 52 53 53 template<typename MarkHook> 54 void genericAddPointer(void*, TinyBloomFilter, MarkHook&);54 void genericAddPointer(void*, int64_t heapVersion, TinyBloomFilter, MarkHook&); 55 55 56 56 template<typename MarkHook> … … 59 59 void grow(); 60 60 61 JSCell** m_roots;61 HeapCell** m_roots; 62 62 size_t m_size; 63 63 size_t m_capacity; 64 MarkedBlockSet* m_blocks; 65 CopiedSpace* m_copiedSpace; 66 JSCell* m_inlineRoots[inlineCapacity]; 64 Heap& m_heap; 65 HeapCell* m_inlineRoots[inlineCapacity]; 67 66 }; 68 67 … … 72 71 } 73 72 74 inline JSCell** ConservativeRoots::roots()73 inline HeapCell** ConservativeRoots::roots() 75 74 { 76 75 return m_roots; -
trunk/Source/JavaScriptCore/heap/CopyToken.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 31 31 enum CopyToken { 32 ButterflyCopyToken,33 32 TypedArrayVectorCopyToken, 34 33 MapBackingStoreCopyToken, -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r204912 r205462 32 32 #include "GCActivityCallback.h" 33 33 #include "GCIncomingRefCountedSetInlines.h" 34 #include "GCTypeMap.h" 34 35 #include "HeapHelperPool.h" 35 36 #include "HeapIterationScope.h" … … 41 42 #include "IncrementalSweeper.h" 42 43 #include "Interpreter.h" 44 #include "JITStubRoutineSet.h" 43 45 #include "JITWorklist.h" 44 46 #include "JSCInlines.h" … … 48 50 #include "SamplingProfiler.h" 49 51 #include "ShadowChicken.h" 52 #include "SuperSampler.h" 50 53 #include "TypeProfilerLog.h" 51 54 #include "UnlinkedCodeBlock.h" … … 58 61 #include <wtf/ProcessID.h> 59 62 #include <wtf/RAMSize.h> 63 #include <wtf/SimpleStats.h> 60 64 61 65 #if USE(FOUNDATION) … … 75 79 76 80 static const size_t largeHeapSize = 32 * MB; // About 1.5X the average webpage. 77 static const size_t smallHeapSize = 1 * MB; // Matches the FastMalloc per-thread cache. 78 79 #define ENABLE_GC_LOGGING 0 80 81 #if ENABLE(GC_LOGGING) 82 #if COMPILER(CLANG) 83 #define DEFINE_GC_LOGGING_GLOBAL(type, name, arguments) \ 84 _Pragma("clang diagnostic push") \ 85 _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ 86 _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \ 87 static type name arguments; \ 88 _Pragma("clang diagnostic pop") 89 #else 90 #define DEFINE_GC_LOGGING_GLOBAL(type, name, arguments) \ 91 static type name arguments; 92 #endif // COMPILER(CLANG) 93 94 struct GCTimer { 95 GCTimer(const char* name) 96 : name(name) 97 { 98 } 99 ~GCTimer() 100 { 101 logData(allCollectionData, "(All)"); 102 logData(edenCollectionData, "(Eden)"); 103 logData(fullCollectionData, "(Full)"); 104 } 105 106 struct TimeRecord { 107 TimeRecord() 108 : time(0) 109 , min(std::numeric_limits<double>::infinity()) 110 , max(0) 111 , count(0) 112 { 113 } 114 115 double time; 116 double min; 117 double max; 118 size_t count; 119 }; 120 121 void logData(const TimeRecord& data, const char* extra) 122 { 123 dataLogF("[%d] %s (Parent: %s) %s: %.2lfms (avg. %.2lf, min. %.2lf, max. %.2lf, count %lu)\n", 124 getCurrentProcessID(), 125 name, 126 parent ? parent->name : "nullptr", 127 extra, 128 data.time * 1000, 129 data.time * 1000 / data.count, 130 data.min * 1000, 131 data.max * 1000, 132 data.count); 133 } 134 135 void updateData(TimeRecord& data, double duration) 136 { 137 if (duration < data.min) 138 data.min = duration; 139 if (duration > data.max) 140 data.max = duration; 141 data.count++; 142 data.time += duration; 143 } 144 145 void didFinishPhase(HeapOperation collectionType, double duration) 146 { 147 TimeRecord& data = collectionType == EdenCollection ? edenCollectionData : fullCollectionData; 148 updateData(data, duration); 149 updateData(allCollectionData, duration); 150 } 151 152 static GCTimer* s_currentGlobalTimer; 153 154 TimeRecord allCollectionData; 155 TimeRecord fullCollectionData; 156 TimeRecord edenCollectionData; 157 const char* name; 158 GCTimer* parent { nullptr }; 159 }; 160 161 GCTimer* GCTimer::s_currentGlobalTimer = nullptr; 162 163 struct GCTimerScope { 164 GCTimerScope(GCTimer& timer, HeapOperation collectionType) 165 : timer(timer) 166 , start(WTF::monotonicallyIncreasingTime()) 167 , collectionType(collectionType) 168 { 169 timer.parent = GCTimer::s_currentGlobalTimer; 170 GCTimer::s_currentGlobalTimer = &timer; 171 } 172 ~GCTimerScope() 173 { 174 double delta = WTF::monotonicallyIncreasingTime() - start; 175 timer.didFinishPhase(collectionType, delta); 176 GCTimer::s_currentGlobalTimer = timer.parent; 177 } 178 GCTimer& timer; 179 double start; 180 HeapOperation collectionType; 181 }; 182 183 struct GCCounter { 184 GCCounter(const char* name) 185 : name(name) 186 , count(0) 187 , total(0) 188 , min(10000000) 189 , max(0) 190 { 191 } 192 193 void add(size_t amount) 194 { 195 count++; 196 total += amount; 197 if (amount < min) 198 min = amount; 199 if (amount > max) 200 max = amount; 201 } 202 ~GCCounter() 203 { 204 dataLogF("[%d] %s: %zu values (avg. %zu, min. %zu, max. %zu)\n", getCurrentProcessID(), name, total, total / count, min, max); 205 } 206 const char* name; 207 size_t count; 208 size_t total; 209 size_t min; 210 size_t max; 211 }; 212 213 #define GCPHASE(name) DEFINE_GC_LOGGING_GLOBAL(GCTimer, name##Timer, (#name)); GCTimerScope name##TimerScope(name##Timer, m_operationInProgress) 214 #define GCCOUNTER(name, value) do { DEFINE_GC_LOGGING_GLOBAL(GCCounter, name##Counter, (#name)); name##Counter.add(value); } while (false) 215 216 #else 217 218 #define GCPHASE(name) do { } while (false) 219 #define GCCOUNTER(name, value) do { } while (false) 220 #endif 221 222 static inline size_t minHeapSize(HeapType heapType, size_t ramSize) 81 const size_t smallHeapSize = 1 * MB; // Matches the FastMalloc per-thread cache. 82 83 size_t minHeapSize(HeapType heapType, size_t ramSize) 223 84 { 224 85 if (heapType == LargeHeap) … … 227 88 } 228 89 229 s tatic inline size_t proportionalHeapSize(size_t heapSize, size_t ramSize)90 size_t proportionalHeapSize(size_t heapSize, size_t ramSize) 230 91 { 231 92 // Try to stay under 1/2 RAM size to leave room for the DOM, rendering, networking, etc. … … 237 98 } 238 99 239 static inlinebool isValidSharedInstanceThreadState(VM* vm)100 bool isValidSharedInstanceThreadState(VM* vm) 240 101 { 241 102 return vm->currentThreadIsHoldingAPILock(); 242 103 } 243 104 244 static inlinebool isValidThreadState(VM* vm)105 bool isValidThreadState(VM* vm) 245 106 { 246 107 if (vm->atomicStringTable() != wtfThreadData().atomicStringTable()) … … 253 114 } 254 115 255 static inlinevoid recordType(TypeCountSet& set, JSCell* cell)116 void recordType(TypeCountSet& set, JSCell* cell) 256 117 { 257 118 const char* typeName = "[unknown]"; … … 261 122 set.add(typeName); 262 123 } 124 125 bool measurePhaseTiming() 126 { 127 return false; 128 } 129 130 HashMap<const char*, GCTypeMap<SimpleStats>>& timingStats() 131 { 132 static HashMap<const char*, GCTypeMap<SimpleStats>>* result; 133 static std::once_flag once; 134 std::call_once( 135 once, 136 [] { 137 result = new HashMap<const char*, GCTypeMap<SimpleStats>>(); 138 }); 139 return *result; 140 } 141 142 SimpleStats& timingStats(const char* name, HeapOperation operation) 143 { 144 return timingStats().add(name, GCTypeMap<SimpleStats>()).iterator->value[operation]; 145 } 146 147 class TimingScope { 148 public: 149 TimingScope(HeapOperation operation, const char* name) 150 : m_operation(operation) 151 , m_name(name) 152 { 153 if (measurePhaseTiming()) 154 m_before = monotonicallyIncreasingTimeMS(); 155 } 156 157 TimingScope(Heap& heap, const char* name) 158 : TimingScope(heap.operationInProgress(), name) 159 { 160 } 161 162 void setOperation(HeapOperation operation) 163 { 164 m_operation = operation; 165 } 166 167 void setOperation(Heap& heap) 168 { 169 setOperation(heap.operationInProgress()); 170 } 171 172 ~TimingScope() 173 { 174 if (measurePhaseTiming()) { 175 double after = monotonicallyIncreasingTimeMS(); 176 double timing = after - m_before; 177 SimpleStats& stats = timingStats(m_name, m_operation); 178 stats.add(timing); 179 dataLog("[GC:", m_operation, "] ", m_name, " took: ", timing, " ms (average ", stats.mean(), " ms).\n"); 180 } 181 } 182 private: 183 HeapOperation m_operation; 184 double m_before; 185 const char* m_name; 186 }; 263 187 264 188 } // anonymous namespace … … 288 212 , m_slotVisitor(*this) 289 213 , m_handleSet(vm) 214 , m_codeBlocks(std::make_unique<CodeBlockSet>()) 215 , m_jitStubRoutines(std::make_unique<JITStubRoutineSet>()) 290 216 , m_isSafeToCollect(false) 291 217 , m_writeBarrierBuffer(256) … … 332 258 333 259 m_arrayBuffers.lastChanceToFinalize(); 334 m_codeBlocks .lastChanceToFinalize();260 m_codeBlocks->lastChanceToFinalize(); 335 261 m_objectSpace.lastChanceToFinalize(); 336 262 releaseDelayedReleasedObjects(); … … 435 361 void Heap::finalizeUnconditionalFinalizers() 436 362 { 437 GCPHASE(FinalizeUnconditionalFinalizers);438 363 m_slotVisitor.finalizeUnconditionalFinalizers(); 439 364 } … … 461 386 void Heap::markRoots(double gcStartTime, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters) 462 387 { 463 GCPHASE(MarkRoots); 388 TimingScope markRootsTimingScope(*this, "Heap::markRoots"); 389 464 390 ASSERT(isValidThreadState(m_vm)); 465 391 466 // We gather conservative roots before clearing mark bits because conservative 467 // gathering uses the mark bits to determine whether a reference is valid. 468 ConservativeRoots conservativeRoots(&m_objectSpace.blocks(), &m_storageSpace); 469 gatherStackRoots(conservativeRoots, stackOrigin, stackTop, calleeSavedRegisters); 470 gatherJSStackRoots(conservativeRoots); 471 gatherScratchBufferRoots(conservativeRoots); 392 HeapRootVisitor heapRootVisitor(m_slotVisitor); 393 394 ConservativeRoots conservativeRoots(*this); 395 { 396 TimingScope preConvergenceTimingScope(*this, "Heap::markRoots before convergence"); 397 // We gather conservative roots before clearing mark bits because conservative 398 // gathering uses the mark bits to determine whether a reference is valid. 399 { 400 TimingScope preConvergenceTimingScope(*this, "Heap::markRoots conservative scan"); 401 SuperSamplerScope superSamplerScope(false); 402 gatherStackRoots(conservativeRoots, stackOrigin, stackTop, calleeSavedRegisters); 403 gatherJSStackRoots(conservativeRoots); 404 gatherScratchBufferRoots(conservativeRoots); 405 } 472 406 473 407 #if ENABLE(DFG_JIT) 474 DFG::rememberCodeBlocks(*m_vm);408 DFG::rememberCodeBlocks(*m_vm); 475 409 #endif 476 410 477 411 #if ENABLE(SAMPLING_PROFILER) 478 if (SamplingProfiler* samplingProfiler = m_vm->samplingProfiler()) {479 // Note that we need to own the lock from now until we're done480 // marking the SamplingProfiler's data because once we verify the481 // SamplingProfiler's stack traces, we don't want it to accumulate482 // more stack traces before we get the chance to mark it.483 // This lock is released inside visitSamplingProfiler().484 samplingProfiler->getLock().lock();485 samplingProfiler->processUnverifiedStackTraces();486 }412 if (SamplingProfiler* samplingProfiler = m_vm->samplingProfiler()) { 413 // Note that we need to own the lock from now until we're done 414 // marking the SamplingProfiler's data because once we verify the 415 // SamplingProfiler's stack traces, we don't want it to accumulate 416 // more stack traces before we get the chance to mark it. 417 // This lock is released inside visitSamplingProfiler(). 418 samplingProfiler->getLock().lock(); 419 samplingProfiler->processUnverifiedStackTraces(); 420 } 487 421 #endif // ENABLE(SAMPLING_PROFILER) 488 422 489 if (m_operationInProgress == FullCollection) { 490 m_opaqueRoots.clear(); 491 m_slotVisitor.clearMarkStack(); 492 } 493 494 clearLivenessData(); 495 496 m_parallelMarkersShouldExit = false; 497 498 m_helperClient.setFunction( 499 [this] () { 500 SlotVisitor* slotVisitor; 501 { 502 LockHolder locker(m_parallelSlotVisitorLock); 503 if (m_availableParallelSlotVisitors.isEmpty()) { 504 std::unique_ptr<SlotVisitor> newVisitor = 505 std::make_unique<SlotVisitor>(*this); 506 slotVisitor = newVisitor.get(); 507 m_parallelSlotVisitors.append(WTFMove(newVisitor)); 508 } else 509 slotVisitor = m_availableParallelSlotVisitors.takeLast(); 510 } 511 512 WTF::registerGCThread(); 513 514 { 515 ParallelModeEnabler parallelModeEnabler(*slotVisitor); 516 slotVisitor->didStartMarking(); 517 slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); 518 } 519 520 { 521 LockHolder locker(m_parallelSlotVisitorLock); 522 m_availableParallelSlotVisitors.append(slotVisitor); 523 } 524 }); 525 526 m_slotVisitor.didStartMarking(); 527 528 HeapRootVisitor heapRootVisitor(m_slotVisitor); 529 530 { 423 if (m_operationInProgress == FullCollection) { 424 m_opaqueRoots.clear(); 425 m_slotVisitor.clearMarkStack(); 426 } 427 428 clearLivenessData(); 429 430 m_parallelMarkersShouldExit = false; 431 432 m_helperClient.setFunction( 433 [this] () { 434 SlotVisitor* slotVisitor; 435 { 436 LockHolder locker(m_parallelSlotVisitorLock); 437 if (m_availableParallelSlotVisitors.isEmpty()) { 438 std::unique_ptr<SlotVisitor> newVisitor = 439 std::make_unique<SlotVisitor>(*this); 440 slotVisitor = newVisitor.get(); 441 m_parallelSlotVisitors.append(WTFMove(newVisitor)); 442 } else 443 slotVisitor = m_availableParallelSlotVisitors.takeLast(); 444 } 445 446 WTF::registerGCThread(); 447 448 { 449 ParallelModeEnabler parallelModeEnabler(*slotVisitor); 450 slotVisitor->didStartMarking(); 451 slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); 452 } 453 454 { 455 LockHolder locker(m_parallelSlotVisitorLock); 456 m_availableParallelSlotVisitors.append(slotVisitor); 457 } 458 }); 459 460 m_slotVisitor.didStartMarking(); 461 } 462 463 { 464 SuperSamplerScope superSamplerScope(false); 465 TimingScope convergenceTimingScope(*this, "Heap::markRoots convergence"); 531 466 ParallelModeEnabler enabler(m_slotVisitor); 532 467 533 468 m_slotVisitor.donateAndDrain(); 534 469 visitExternalRememberedSet(); … … 545 480 converge(); 546 481 } 482 483 TimingScope postConvergenceTimingScope(*this, "Heap::markRoots after convergence"); 547 484 548 485 // Weak references must be marked last because their liveness depends on … … 562 499 void Heap::copyBackingStores() 563 500 { 564 GCPHASE(CopyBackingStores);501 SuperSamplerScope superSamplerScope(false); 565 502 if (m_operationInProgress == EdenCollection) 566 503 m_storageSpace.startedCopying<EdenCollection>(); … … 599 536 CopyWorkList& workList = block->workList(); 600 537 for (CopyWorklistItem item : workList) { 601 if (item.token() == ButterflyCopyToken) {602 JSObject::copyBackingStore(603 item.cell(), copyVisitor, ButterflyCopyToken);604 continue;605 }606 607 538 item.cell()->methodTable()->copyBackingStore( 608 539 item.cell(), copyVisitor, item.token()); … … 620 551 void Heap::gatherStackRoots(ConservativeRoots& roots, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters) 621 552 { 622 GCPHASE(GatherStackRoots); 623 m_jitStubRoutines.clearMarks(); 624 m_machineThreads.gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks, stackOrigin, stackTop, calleeSavedRegisters); 553 m_jitStubRoutines->clearMarks(); 554 m_machineThreads.gatherConservativeRoots(roots, *m_jitStubRoutines, *m_codeBlocks, stackOrigin, stackTop, calleeSavedRegisters); 625 555 } 626 556 … … 628 558 { 629 559 #if !ENABLE(JIT) 630 GCPHASE(GatherJSStackRoots); 631 m_vm->interpreter->cloopStack().gatherConservativeRoots(roots, m_jitStubRoutines, m_codeBlocks); 560 m_vm->interpreter->cloopStack().gatherConservativeRoots(roots, *m_jitStubRoutines, *m_codeBlocks); 632 561 #else 633 562 UNUSED_PARAM(roots); … … 638 567 { 639 568 #if ENABLE(DFG_JIT) 640 GCPHASE(GatherScratchBufferRoots);641 569 m_vm->gatherConservativeRoots(roots); 642 570 #else … … 647 575 void Heap::clearLivenessData() 648 576 { 649 GCPHASE(ClearLivenessData);577 TimingScope timingScope(*this, "Heap::clearLivenessData"); 650 578 if (m_operationInProgress == FullCollection) 651 m_codeBlocks.clearMarksForFullCollection(); 652 653 m_objectSpace.clearNewlyAllocated(); 654 m_objectSpace.clearMarks(); 579 m_codeBlocks->clearMarksForFullCollection(); 580 581 { 582 TimingScope clearNewlyAllocatedTimingScope(*this, "m_objectSpace.clearNewlyAllocated"); 583 m_objectSpace.clearNewlyAllocated(); 584 } 585 586 { 587 TimingScope clearMarksTimingScope(*this, "m_objectSpace.clearMarks"); 588 m_objectSpace.flip(); 589 } 655 590 } 656 591 … … 664 599 void Heap::visitSmallStrings() 665 600 { 666 GCPHASE(VisitSmallStrings);667 601 if (!m_vm->smallStrings.needsToBeVisited(m_operationInProgress)) 668 602 return; … … 676 610 void Heap::visitConservativeRoots(ConservativeRoots& roots) 677 611 { 678 GCPHASE(VisitConservativeRoots);679 612 m_slotVisitor.append(roots); 680 613 … … 699 632 { 700 633 #if ENABLE(DFG_JIT) 701 GCPHASE(FinalizeDFGWorklists);702 634 for (auto worklist : m_suspendedCompilerWorklists) 703 635 worklist->removeDeadPlans(*m_vm); … … 733 665 void Heap::gatherExtraHeapSnapshotData(HeapProfiler& heapProfiler) 734 666 { 735 GCPHASE(GatherExtraHeapSnapshotData);736 667 if (HeapSnapshotBuilder* builder = heapProfiler.activeSnapshotBuilder()) { 737 668 HeapIterationScope heapIterationScope(*this); … … 759 690 void Heap::removeDeadHeapSnapshotNodes(HeapProfiler& heapProfiler) 760 691 { 761 GCPHASE(RemoveDeadHeapSnapshotNodes);762 692 if (HeapSnapshot* snapshot = heapProfiler.mostRecentSnapshot()) { 763 693 HeapIterationScope heapIterationScope(*this); … … 770 700 void Heap::visitProtectedObjects(HeapRootVisitor& heapRootVisitor) 771 701 { 772 GCPHASE(VisitProtectedObjects);773 774 702 for (auto& pair : m_protectedValues) 775 703 heapRootVisitor.visit(&pair.key); … … 783 711 void Heap::visitArgumentBuffers(HeapRootVisitor& visitor) 784 712 { 785 GCPHASE(MarkingArgumentBuffers);786 713 if (!m_markListSet || !m_markListSet->size()) 787 714 return; … … 797 724 void Heap::visitException(HeapRootVisitor& visitor) 798 725 { 799 GCPHASE(MarkingException);800 726 if (!m_vm->exception() && !m_vm->lastException()) 801 727 return; … … 812 738 void Heap::visitStrongHandles(HeapRootVisitor& visitor) 813 739 { 814 GCPHASE(VisitStrongHandles);815 740 m_handleSet.visitStrongHandles(visitor); 816 741 … … 823 748 void Heap::visitHandleStack(HeapRootVisitor& visitor) 824 749 { 825 GCPHASE(VisitHandleStack);826 750 m_handleStack.visit(visitor); 827 751 … … 837 761 if (SamplingProfiler* samplingProfiler = m_vm->samplingProfiler()) { 838 762 ASSERT(samplingProfiler->getLock().isLocked()); 839 GCPHASE(VisitSamplingProfiler);840 763 samplingProfiler->visit(m_slotVisitor); 841 764 if (Options::logGC() == GCLogging::Verbose) … … 855 778 void Heap::traceCodeBlocksAndJITStubRoutines() 856 779 { 857 GCPHASE(TraceCodeBlocksAndJITStubRoutines); 858 m_jitStubRoutines.traceMarkedStubRoutines(m_slotVisitor); 780 m_jitStubRoutines->traceMarkedStubRoutines(m_slotVisitor); 859 781 860 782 if (Options::logGC() == GCLogging::Verbose) … … 866 788 void Heap::converge() 867 789 { 868 GCPHASE(Convergence);869 790 m_slotVisitor.drainFromShared(SlotVisitor::MasterDrain); 870 791 } … … 872 793 void Heap::visitWeakHandles(HeapRootVisitor& visitor) 873 794 { 874 GCPHASE(VisitingLiveWeakHandles);795 TimingScope timingScope(*this, "Heap::visitWeakHandles"); 875 796 while (true) { 876 m_objectSpace.visitWeakSets(visitor); 797 { 798 TimingScope timingScope(*this, "m_objectSpace.visitWeakSets"); 799 m_objectSpace.visitWeakSets(visitor); 800 } 877 801 harvestWeakReferences(); 878 802 visitCompilerWorklistWeakReferences(); … … 893 817 void Heap::updateObjectCounts(double gcStartTime) 894 818 { 895 GCCOUNTER(VisitedValueCount, m_slotVisitor.visitCount() + threadVisitCount());896 897 819 if (Options::logGC() == GCLogging::Verbose) { 898 820 size_t visitCount = m_slotVisitor.visitCount(); … … 1034 956 void Heap::clearUnmarkedExecutables() 1035 957 { 1036 GCPHASE(ClearUnmarkedExecutables);1037 958 for (unsigned i = m_executables.size(); i--;) { 1038 959 ExecutableBase* current = m_executables[i]; … … 1052 973 void Heap::deleteUnmarkedCompiledCode() 1053 974 { 1054 GCPHASE(DeleteCodeBlocks);1055 975 clearUnmarkedExecutables(); 1056 m_codeBlocks .deleteUnmarkedAndUnreferenced(m_operationInProgress);1057 m_jitStubRoutines .deleteUnmarkedJettisonedStubRoutines();976 m_codeBlocks->deleteUnmarkedAndUnreferenced(m_operationInProgress); 977 m_jitStubRoutines->deleteUnmarkedJettisonedStubRoutines(); 1058 978 } 1059 979 … … 1074 994 void Heap::collectAllGarbage() 1075 995 { 996 SuperSamplerScope superSamplerScope(false); 1076 997 if (!m_isSafeToCollect) 1077 998 return; 1078 999 1079 collect (FullCollection);1000 collectWithoutAnySweep(FullCollection); 1080 1001 1081 1002 DeferGCForAWhile deferGC(*this); … … 1091 1012 } 1092 1013 1093 NEVER_INLINE void Heap::collect(HeapOperation collectionType) 1014 void Heap::collect(HeapOperation collectionType) 1015 { 1016 SuperSamplerScope superSamplerScope(false); 1017 if (!m_isSafeToCollect) 1018 return; 1019 1020 collectWithoutAnySweep(collectionType); 1021 } 1022 1023 NEVER_INLINE void Heap::collectWithoutAnySweep(HeapOperation collectionType) 1094 1024 { 1095 1025 void* stackTop; … … 1103 1033 NEVER_INLINE void Heap::collectImpl(HeapOperation collectionType, void* stackOrigin, void* stackTop, MachineThreads::RegisterState& calleeSavedRegisters) 1104 1034 { 1035 SuperSamplerScope superSamplerScope(false); 1036 TimingScope collectImplTimingScope(collectionType, "Heap::collectImpl"); 1037 1105 1038 #if ENABLE(ALLOCATION_LOGGING) 1106 1039 dataLogF("JSC GC starting collection.\n"); … … 1113 1046 } 1114 1047 1115 if (vm()->typeProfiler()) { 1116 DeferGCForAWhile awhile(*this); 1117 vm()->typeProfilerLog()->processLogEntries(ASCIILiteral("GC")); 1118 } 1048 double gcStartTime; 1049 { 1050 TimingScope earlyTimingScope(collectionType, "Heap::collectImpl before markRoots"); 1051 1052 if (vm()->typeProfiler()) { 1053 DeferGCForAWhile awhile(*this); 1054 vm()->typeProfilerLog()->processLogEntries(ASCIILiteral("GC")); 1055 } 1119 1056 1120 1057 #if ENABLE(JIT) 1121 {1122 DeferGCForAWhile awhile(*this);1123 JITWorklist::instance()->completeAllForVM(*m_vm);1124 }1058 { 1059 DeferGCForAWhile awhile(*this); 1060 JITWorklist::instance()->completeAllForVM(*m_vm); 1061 } 1125 1062 #endif // ENABLE(JIT) 1126 1063 1127 vm()->shadowChicken().update(*vm(), vm()->topCallFrame); 1128 1129 RELEASE_ASSERT(!m_deferralDepth); 1130 ASSERT(vm()->currentThreadIsHoldingAPILock()); 1131 RELEASE_ASSERT(vm()->atomicStringTable() == wtfThreadData().atomicStringTable()); 1132 ASSERT(m_isSafeToCollect); 1133 RELEASE_ASSERT(m_operationInProgress == NoOperation); 1134 1135 suspendCompilerThreads(); 1136 willStartCollection(collectionType); 1137 GCPHASE(Collect); 1138 1139 double gcStartTime = WTF::monotonicallyIncreasingTime(); 1140 if (m_verifier) { 1141 // Verify that live objects from the last GC cycle haven't been corrupted by 1142 // mutators before we begin this new GC cycle. 1143 m_verifier->verify(HeapVerifier::Phase::BeforeGC); 1144 1145 m_verifier->initializeGCCycle(); 1146 m_verifier->gatherLiveObjects(HeapVerifier::Phase::BeforeMarking); 1147 } 1148 1149 flushOldStructureIDTables(); 1150 stopAllocation(); 1151 flushWriteBarrierBuffer(); 1064 vm()->shadowChicken().update(*vm(), vm()->topCallFrame); 1065 1066 RELEASE_ASSERT(!m_deferralDepth); 1067 ASSERT(vm()->currentThreadIsHoldingAPILock()); 1068 RELEASE_ASSERT(vm()->atomicStringTable() == wtfThreadData().atomicStringTable()); 1069 ASSERT(m_isSafeToCollect); 1070 RELEASE_ASSERT(m_operationInProgress == NoOperation); 1071 1072 suspendCompilerThreads(); 1073 willStartCollection(collectionType); 1074 1075 collectImplTimingScope.setOperation(*this); 1076 earlyTimingScope.setOperation(*this); 1077 1078 gcStartTime = WTF::monotonicallyIncreasingTime(); 1079 if (m_verifier) { 1080 // Verify that live objects from the last GC cycle haven't been corrupted by 1081 // mutators before we begin this new GC cycle. 1082 m_verifier->verify(HeapVerifier::Phase::BeforeGC); 1083 1084 m_verifier->initializeGCCycle(); 1085 m_verifier->gatherLiveObjects(HeapVerifier::Phase::BeforeMarking); 1086 } 1087 1088 flushOldStructureIDTables(); 1089 stopAllocation(); 1090 prepareForMarking(); 1091 flushWriteBarrierBuffer(); 1092 } 1152 1093 1153 1094 markRoots(gcStartTime, stackOrigin, stackTop, calleeSavedRegisters); 1095 1096 TimingScope lateTimingScope(*this, "Heap::collectImpl after markRoots"); 1154 1097 1155 1098 if (m_verifier) { … … 1165 1108 sweepArrayBuffers(); 1166 1109 snapshotMarkedSpace(); 1167 1168 1110 copyBackingStores(); 1169 1170 1111 finalizeUnconditionalFinalizers(); 1171 1112 removeDeadCompilerWorklistEntries(); … … 1180 1121 didFinishCollection(gcStartTime); 1181 1122 resumeCompilerThreads(); 1182 1123 sweepLargeAllocations(); 1124 1183 1125 if (m_verifier) { 1184 1126 m_verifier->trimDeadObjects(); … … 1192 1134 } 1193 1135 1136 void Heap::sweepLargeAllocations() 1137 { 1138 m_objectSpace.sweepLargeAllocations(); 1139 } 1140 1194 1141 void Heap::suspendCompilerThreads() 1195 1142 { 1196 1143 #if ENABLE(DFG_JIT) 1197 GCPHASE(SuspendCompilerThreads);1198 1144 ASSERT(m_suspendedCompilerWorklists.isEmpty()); 1199 1145 for (unsigned i = DFG::numberOfWorklists(); i--;) { … … 1208 1154 void Heap::willStartCollection(HeapOperation collectionType) 1209 1155 { 1210 GCPHASE(StartingCollection);1211 1212 1156 if (Options::logGC()) 1213 1157 dataLog("=> "); … … 1247 1191 void Heap::flushOldStructureIDTables() 1248 1192 { 1249 GCPHASE(FlushOldStructureIDTables);1250 1193 m_structureIDTable.flushOldTables(); 1251 1194 } … … 1253 1196 void Heap::flushWriteBarrierBuffer() 1254 1197 { 1255 GCPHASE(FlushWriteBarrierBuffer);1256 1198 if (m_operationInProgress == EdenCollection) { 1257 1199 m_writeBarrierBuffer.flush(*this); … … 1263 1205 void Heap::stopAllocation() 1264 1206 { 1265 GCPHASE(StopAllocation);1266 1207 m_objectSpace.stopAllocating(); 1267 1208 if (m_operationInProgress == FullCollection) … … 1269 1210 } 1270 1211 1212 void Heap::prepareForMarking() 1213 { 1214 m_objectSpace.prepareForMarking(); 1215 } 1216 1271 1217 void Heap::reapWeakHandles() 1272 1218 { 1273 GCPHASE(ReapingWeakHandles);1274 1219 m_objectSpace.reapWeakSets(); 1275 1220 } … … 1277 1222 void Heap::pruneStaleEntriesFromWeakGCMaps() 1278 1223 { 1279 GCPHASE(PruningStaleEntriesFromWeakGCMaps);1280 1224 if (m_operationInProgress != FullCollection) 1281 1225 return; … … 1286 1230 void Heap::sweepArrayBuffers() 1287 1231 { 1288 GCPHASE(SweepingArrayBuffers);1289 1232 m_arrayBuffers.sweep(); 1290 1233 } 1291 1234 1292 1235 struct MarkedBlockSnapshotFunctor : public MarkedBlock::VoidFunctor { 1293 MarkedBlockSnapshotFunctor(Vector<MarkedBlock *>& blocks)1236 MarkedBlockSnapshotFunctor(Vector<MarkedBlock::Handle*>& blocks) 1294 1237 : m_index(0) 1295 1238 , m_blocks(blocks) … … 1297 1240 } 1298 1241 1299 void operator()(MarkedBlock* block) const { m_blocks[m_index++] = block; } 1242 void operator()(MarkedBlock::Handle* block) const 1243 { 1244 block->setIsOnBlocksToSweep(true); 1245 m_blocks[m_index++] = block; 1246 } 1300 1247 1301 1248 // FIXME: This is a mutable field becaue this isn't a C++ lambda. 1302 1249 // https://bugs.webkit.org/show_bug.cgi?id=159644 1303 1250 mutable size_t m_index; 1304 Vector<MarkedBlock *>& m_blocks;1251 Vector<MarkedBlock::Handle*>& m_blocks; 1305 1252 }; 1306 1253 1307 1254 void Heap::snapshotMarkedSpace() 1308 1255 { 1309 GCPHASE(SnapshotMarkedSpace); 1310 1256 TimingScope timingScope(*this, "Heap::snapshotMarkedSpace"); 1257 // FIXME: This should probably be renamed. It's not actually snapshotting all of MarkedSpace. 1258 // This is used by IncrementalSweeper, so it only needs to snapshot blocks. However, if we ever 1259 // wanted to add other snapshotting login, we'd probably put it here. 1260 1311 1261 if (m_operationInProgress == EdenCollection) { 1312 m_blockSnapshot.appendVector(m_objectSpace.blocksWithNewObjects()); 1313 // Sort and deduplicate the block snapshot since we might be appending to an unfinished work list. 1314 std::sort(m_blockSnapshot.begin(), m_blockSnapshot.end()); 1315 m_blockSnapshot.shrink(std::unique(m_blockSnapshot.begin(), m_blockSnapshot.end()) - m_blockSnapshot.begin()); 1262 for (MarkedBlock::Handle* handle : m_objectSpace.blocksWithNewObjects()) { 1263 if (handle->isOnBlocksToSweep()) 1264 continue; 1265 m_blockSnapshot.append(handle); 1266 handle->setIsOnBlocksToSweep(true); 1267 } 1316 1268 } else { 1317 1269 m_blockSnapshot.resizeToFit(m_objectSpace.blocks().set().size()); … … 1323 1275 void Heap::deleteSourceProviderCaches() 1324 1276 { 1325 GCPHASE(DeleteSourceProviderCaches);1326 1277 m_vm->clearSourceProviderCaches(); 1327 1278 } … … 1329 1280 void Heap::notifyIncrementalSweeper() 1330 1281 { 1331 GCPHASE(NotifyIncrementalSweeper);1332 1333 1282 if (m_operationInProgress == FullCollection) { 1334 1283 if (!m_logicallyEmptyWeakBlocks.isEmpty()) … … 1341 1290 void Heap::writeBarrierCurrentlyExecutingCodeBlocks() 1342 1291 { 1343 GCPHASE(WriteBarrierCurrentlyExecutingCodeBlocks); 1344 m_codeBlocks.writeBarrierCurrentlyExecutingCodeBlocks(this); 1292 m_codeBlocks->writeBarrierCurrentlyExecutingCodeBlocks(this); 1345 1293 } 1346 1294 1347 1295 void Heap::resetAllocators() 1348 1296 { 1349 GCPHASE(ResetAllocators);1350 1297 m_objectSpace.resetAllocators(); 1351 1298 } … … 1353 1300 void Heap::updateAllocationLimits() 1354 1301 { 1355 GCPHASE(UpdateAllocationLimits); 1302 static const bool verbose = false; 1303 1304 if (verbose) { 1305 dataLog("\n"); 1306 dataLog("bytesAllocatedThisCycle = ", m_bytesAllocatedThisCycle, "\n"); 1307 } 1356 1308 1357 1309 // Calculate our current heap size threshold for the purpose of figuring out when we should … … 1370 1322 // cells usually have a narrow range of sizes. So, the underestimation is probably OK. 1371 1323 currentHeapSize += m_totalBytesVisited; 1324 if (verbose) 1325 dataLog("totalBytesVisited = ", m_totalBytesVisited, ", currentHeapSize = ", currentHeapSize, "\n"); 1372 1326 1373 1327 // For copied space, we use the capacity of storage space. This is because copied space may get … … 1385 1339 ASSERT(m_totalBytesCopied <= m_storageSpace.size()); 1386 1340 currentHeapSize += m_storageSpace.capacity(); 1341 if (verbose) 1342 dataLog("storageSpace.capacity() = ", m_storageSpace.capacity(), ", currentHeapSize = ", currentHeapSize, "\n"); 1387 1343 1388 1344 // It's up to the user to ensure that extraMemorySize() ends up corresponding to allocation-time 1389 1345 // extra memory reporting. 1390 1346 currentHeapSize += extraMemorySize(); 1347 1348 if (verbose) 1349 dataLog("extraMemorySize() = ", extraMemorySize(), ", currentHeapSize = ", currentHeapSize, "\n"); 1391 1350 1392 1351 if (Options::gcMaxHeapSize() && currentHeapSize > Options::gcMaxHeapSize()) … … 1398 1357 // fixed minimum. 1399 1358 m_maxHeapSize = max(minHeapSize(m_heapType, m_ramSize), proportionalHeapSize(currentHeapSize, m_ramSize)); 1359 if (verbose) 1360 dataLog("Full: maxHeapSize = ", m_maxHeapSize, "\n"); 1400 1361 m_maxEdenSize = m_maxHeapSize - currentHeapSize; 1362 if (verbose) 1363 dataLog("Full: maxEdenSize = ", m_maxEdenSize, "\n"); 1401 1364 m_sizeAfterLastFullCollect = currentHeapSize; 1365 if (verbose) 1366 dataLog("Full: sizeAfterLastFullCollect = ", currentHeapSize, "\n"); 1402 1367 m_bytesAbandonedSinceLastFullCollect = 0; 1368 if (verbose) 1369 dataLog("Full: bytesAbandonedSinceLastFullCollect = ", 0, "\n"); 1403 1370 } else { 1404 static const bool verbose = false;1405 1406 1371 ASSERT(currentHeapSize >= m_sizeAfterLastCollect); 1407 m_maxEdenSize = m_maxHeapSize - currentHeapSize; 1372 // Theoretically, we shouldn't ever scan more memory than the heap size we planned to have. 1373 // But we are sloppy, so we have to defend against the overflow. 1374 m_maxEdenSize = currentHeapSize > m_maxHeapSize ? 0 : m_maxHeapSize - currentHeapSize; 1375 if (verbose) 1376 dataLog("Eden: maxEdenSize = ", m_maxEdenSize, "\n"); 1408 1377 m_sizeAfterLastEdenCollect = currentHeapSize; 1409 if (verbose) { 1410 dataLog("Max heap size: ", m_maxHeapSize, "\n"); 1411 dataLog("Current heap size: ", currentHeapSize, "\n"); 1412 dataLog("Size after last eden collection: ", m_sizeAfterLastEdenCollect, "\n"); 1413 } 1378 if (verbose) 1379 dataLog("Eden: sizeAfterLastEdenCollect = ", currentHeapSize, "\n"); 1414 1380 double edenToOldGenerationRatio = (double)m_maxEdenSize / (double)m_maxHeapSize; 1415 if (verbose)1416 dataLog("Eden to old generation ratio: ", edenToOldGenerationRatio, "\n");1417 1381 double minEdenToOldGenerationRatio = 1.0 / 3.0; 1418 1382 if (edenToOldGenerationRatio < minEdenToOldGenerationRatio) … … 1420 1384 // This seems suspect at first, but what it does is ensure that the nursery size is fixed. 1421 1385 m_maxHeapSize += currentHeapSize - m_sizeAfterLastCollect; 1386 if (verbose) 1387 dataLog("Eden: maxHeapSize = ", m_maxHeapSize, "\n"); 1422 1388 m_maxEdenSize = m_maxHeapSize - currentHeapSize; 1389 if (verbose) 1390 dataLog("Eden: maxEdenSize = ", m_maxEdenSize, "\n"); 1423 1391 if (m_fullActivityCallback) { 1424 1392 ASSERT(currentHeapSize >= m_sizeAfterLastFullCollect); … … 1428 1396 1429 1397 m_sizeAfterLastCollect = currentHeapSize; 1398 if (verbose) 1399 dataLog("sizeAfterLastCollect = ", m_sizeAfterLastCollect, "\n"); 1430 1400 m_bytesAllocatedThisCycle = 0; 1431 1401 … … 1436 1406 void Heap::didFinishCollection(double gcStartTime) 1437 1407 { 1438 GCPHASE(FinishingCollection);1439 1408 double gcEndTime = WTF::monotonicallyIncreasingTime(); 1440 1409 HeapOperation operation = m_operationInProgress; … … 1472 1441 { 1473 1442 #if ENABLE(DFG_JIT) 1474 GCPHASE(ResumeCompilerThreads);1475 1443 for (auto worklist : m_suspendedCompilerWorklists) 1476 1444 worklist->resumeAllThreads(); … … 1581 1549 current++; 1582 1550 1583 void* limit = static_cast<void*>(reinterpret_cast<char*>(cell) + MarkedBlock::blockFor(cell)->cellSize());1551 void* limit = static_cast<void*>(reinterpret_cast<char*>(cell) + cell->cellSize()); 1584 1552 for (; current < limit; current++) 1585 1553 *current = zombifiedBits; … … 1687 1655 } 1688 1656 1657 void Heap::forEachCodeBlockImpl(const ScopedLambda<bool(CodeBlock*)>& func) 1658 { 1659 // We don't know the full set of CodeBlocks until compilation has terminated. 1660 completeAllJITPlans(); 1661 1662 return m_codeBlocks->iterate(func); 1663 } 1664 1689 1665 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/Heap.h
r204912 r205462 24 24 25 25 #include "ArrayBuffer.h" 26 #include "CodeBlockSet.h"27 26 #include "CopyVisitor.h" 28 27 #include "GCIncomingRefCountedSet.h" … … 31 30 #include "HeapObserver.h" 32 31 #include "HeapOperation.h" 33 #include "JITStubRoutineSet.h"34 32 #include "ListableHandler.h" 35 33 #include "MachineStackMarker.h" … … 54 52 55 53 class CodeBlock; 54 class CodeBlockSet; 56 55 class CopiedSpace; 57 56 class EdenGCActivityCallback; … … 66 65 class IncrementalSweeper; 67 66 class JITStubRoutine; 67 class JITStubRoutineSet; 68 68 class JSCell; 69 69 class JSValue; … … 83 83 84 84 enum HeapType { SmallHeap, LargeHeap }; 85 86 class HeapUtil; 85 87 86 88 class Heap { … … 90 92 friend class DFG::SpeculativeJIT; 91 93 static Heap* heap(const JSValue); // 0 for immediate values 92 static Heap* heap(const JSCell*);94 static Heap* heap(const HeapCell*); 93 95 94 96 // This constant determines how many blocks we iterate between checks of our … … 100 102 static bool isLive(const void*); 101 103 static bool isMarked(const void*); 102 static bool testAndSetMarked( const void*);104 static bool testAndSetMarked(int64_t, const void*); 103 105 static void setMarked(const void*); 104 105 // This function must be run after stopAllocation() is called and 106 // before liveness data is cleared to be accurate. 107 static bool isPointerGCObject(TinyBloomFilter, MarkedBlockSet&, void* pointer); 108 static bool isValueGCObject(TinyBloomFilter, MarkedBlockSet&, JSValue); 106 107 static size_t cellSize(const void*); 109 108 110 109 void writeBarrier(const JSCell*); … … 148 147 MarkedSpace::Subspace& subspaceForAuxiliaryData() { return m_objectSpace.subspaceForAuxiliaryData(); } 149 148 template<typename ClassType> MarkedSpace::Subspace& subspaceForObjectOfType(); 150 MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); } 151 MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); } 152 template<typename ClassType> MarkedAllocator& allocatorForObjectOfType(size_t bytes); 149 MarkedAllocator* allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); } 150 MarkedAllocator* allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); } 151 template<typename ClassType> MarkedAllocator* allocatorForObjectOfType(size_t bytes); 152 MarkedAllocator* allocatorForAuxiliaryData(size_t bytes) { return m_objectSpace.auxiliaryAllocatorFor(bytes); } 153 153 CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); } 154 void* allocateAuxiliary(JSCell* intendedOwner, size_t); 155 void* tryAllocateAuxiliary(JSCell* intendedOwner, size_t); 156 void* tryReallocateAuxiliary(JSCell* intendedOwner, void* oldBase, size_t oldSize, size_t newSize); 154 157 CheckedBoolean tryAllocateStorage(JSCell* intendedOwner, size_t, void**); 155 158 CheckedBoolean tryReallocateStorage(JSCell* intendedOwner, void**, size_t, size_t); … … 231 234 bool isPagedOut(double deadline); 232 235 233 const JITStubRoutineSet& jitStubRoutines() { return m_jitStubRoutines; }236 const JITStubRoutineSet& jitStubRoutines() { return *m_jitStubRoutines; } 234 237 235 238 void addReference(JSCell*, ArrayBuffer*); … … 239 242 StructureIDTable& structureIDTable() { return m_structureIDTable; } 240 243 241 CodeBlockSet& codeBlockSet() { return m_codeBlocks; }244 CodeBlockSet& codeBlockSet() { return *m_codeBlocks; } 242 245 243 246 #if USE(FOUNDATION) … … 268 271 friend class GCThread; 269 272 friend class HandleSet; 273 friend class HeapUtil; 270 274 friend class HeapVerifier; 271 275 friend class JITStubRoutine; … … 284 288 template<typename T> friend void* allocateCell(Heap&, size_t); 285 289 290 void collectWithoutAnySweep(HeapOperation collectionType = AnyCollection); 291 286 292 void* allocateWithDestructor(size_t); // For use with objects with destructors. 287 293 void* allocateWithoutDestructor(size_t); // For use with objects without destructors. … … 305 311 void flushWriteBarrierBuffer(); 306 312 void stopAllocation(); 313 void prepareForMarking(); 307 314 308 315 void markRoots(double gcStartTime, void* stackOrigin, void* stackTop, MachineThreads::RegisterState&); … … 349 356 void gatherExtraHeapSnapshotData(HeapProfiler&); 350 357 void removeDeadHeapSnapshotNodes(HeapProfiler&); 351 358 void sweepLargeAllocations(); 359 352 360 void sweepAllLogicallyEmptyWeakBlocks(); 353 361 bool sweepNextLogicallyEmptyWeakBlock(); … … 362 370 size_t threadBytesVisited(); 363 371 size_t threadBytesCopied(); 372 373 void forEachCodeBlockImpl(const ScopedLambda<bool(CodeBlock*)>&); 364 374 365 375 const HeapType m_heapType; … … 409 419 HandleSet m_handleSet; 410 420 HandleStack m_handleStack; 411 CodeBlockSetm_codeBlocks;412 JITStubRoutineSetm_jitStubRoutines;421 std::unique_ptr<CodeBlockSet> m_codeBlocks; 422 std::unique_ptr<JITStubRoutineSet> m_jitStubRoutines; 413 423 FinalizerOwner m_finalizerOwner; 414 424 … … 429 439 RefPtr<GCActivityCallback> m_edenActivityCallback; 430 440 std::unique_ptr<IncrementalSweeper> m_sweeper; 431 Vector<MarkedBlock *> m_blockSnapshot;441 Vector<MarkedBlock::Handle*> m_blockSnapshot; 432 442 433 443 Vector<HeapObserver*> m_observers; -
trunk/Source/JavaScriptCore/heap/HeapCell.h
r204912 r205462 26 26 #pragma once 27 27 28 #include "DestructionMode.h" 29 28 30 namespace JSC { 31 32 class CellContainer; 33 class Heap; 34 class LargeAllocation; 35 class MarkedBlock; 36 class VM; 37 struct AllocatorAttributes; 29 38 30 39 class HeapCell { … … 39 48 void zap() { *reinterpret_cast<uintptr_t**>(this) = 0; } 40 49 bool isZapped() const { return !*reinterpret_cast<uintptr_t* const*>(this); } 50 51 bool isLargeAllocation() const; 52 CellContainer cellContainer() const; 53 MarkedBlock& markedBlock() const; 54 LargeAllocation& largeAllocation() const; 55 56 // If you want performance and you know that your cell is small, you can do this instead: 57 // ASSERT(!cell->isLargeAllocation()); 58 // cell->markedBlock().vm() 59 // We currently only use this hack for callees to make ExecState::vm() fast. It's not 60 // recommended to use it for too many other things, since the large allocation cutoff is 61 // a runtime option and its default value is small (400 bytes). 62 Heap* heap() const; 63 VM* vm() const; 64 65 size_t cellSize() const; 66 AllocatorAttributes allocatorAttributes() const; 67 DestructionMode destructionMode() const; 68 Kind cellKind() const; 41 69 }; 42 70 -
trunk/Source/JavaScriptCore/heap/HeapInlines.h
r204912 r205462 29 29 #include "CopyBarrier.h" 30 30 #include "Heap.h" 31 #include "HeapCellInlines.h" 32 #include "IndexingHeader.h" 33 #include "JSCallee.h" 31 34 #include "JSCell.h" 32 35 #include "Structure.h" … … 60 63 } 61 64 62 inline Heap* Heap::heap(const JSCell* cell)63 { 64 return MarkedBlock::blockFor(cell)->heap();65 ALWAYS_INLINE Heap* Heap::heap(const HeapCell* cell) 66 { 67 return cell->heap(); 65 68 } 66 69 … … 72 75 } 73 76 74 inline bool Heap::isLive(const void* cell) 75 { 76 return MarkedBlock::blockFor(cell)->isLiveCell(cell); 77 } 78 79 inline bool Heap::isMarked(const void* cell) 80 { 81 return MarkedBlock::blockFor(cell)->isMarked(cell); 82 } 83 84 inline bool Heap::testAndSetMarked(const void* cell) 85 { 86 return MarkedBlock::blockFor(cell)->testAndSetMarked(cell); 87 } 88 89 inline void Heap::setMarked(const void* cell) 90 { 91 MarkedBlock::blockFor(cell)->setMarked(cell); 77 inline bool Heap::isLive(const void* rawCell) 78 { 79 HeapCell* cell = bitwise_cast<HeapCell*>(rawCell); 80 if (cell->isLargeAllocation()) 81 return cell->largeAllocation().isLive(); 82 MarkedBlock& block = cell->markedBlock(); 83 block.flipIfNecessary(block.vm()->heap.objectSpace().version()); 84 return block.handle().isLiveCell(cell); 85 } 86 87 ALWAYS_INLINE bool Heap::isMarked(const void* rawCell) 88 { 89 HeapCell* cell = bitwise_cast<HeapCell*>(rawCell); 90 if (cell->isLargeAllocation()) 91 return cell->largeAllocation().isMarked(); 92 MarkedBlock& block = cell->markedBlock(); 93 block.flipIfNecessary(block.vm()->heap.objectSpace().version()); 94 return block.isMarked(cell); 95 } 96 97 ALWAYS_INLINE bool Heap::testAndSetMarked(int64_t version, const void* rawCell) 98 { 99 HeapCell* cell = bitwise_cast<HeapCell*>(rawCell); 100 if (cell->isLargeAllocation()) 101 return cell->largeAllocation().testAndSetMarked(); 102 MarkedBlock& block = cell->markedBlock(); 103 block.flipIfNecessaryConcurrently(version); 104 return block.testAndSetMarked(cell); 105 } 106 107 inline void Heap::setMarked(const void* rawCell) 108 { 109 HeapCell* cell = bitwise_cast<HeapCell*>(rawCell); 110 if (cell->isLargeAllocation()) { 111 cell->largeAllocation().setMarked(); 112 return; 113 } 114 MarkedBlock& block = cell->markedBlock(); 115 block.flipIfNecessary(block.vm()->heap.objectSpace().version()); 116 block.setMarked(cell); 117 } 118 119 ALWAYS_INLINE size_t Heap::cellSize(const void* rawCell) 120 { 121 return bitwise_cast<HeapCell*>(rawCell)->cellSize(); 92 122 } 93 123 … … 166 196 } 167 197 168 template<typename Functor> inline void Heap::forEachCodeBlock(const Functor& functor) 169 { 170 // We don't know the full set of CodeBlocks until compilation has terminated. 171 completeAllJITPlans(); 172 173 return m_codeBlocks.iterate<Functor>(functor); 198 template<typename Functor> inline void Heap::forEachCodeBlock(const Functor& func) 199 { 200 forEachCodeBlockImpl(scopedLambdaRef<bool(CodeBlock*)>(func)); 174 201 } 175 202 … … 200 227 201 228 template<typename ClassType> 202 void* Heap::allocateObjectOfType(size_t bytes)229 inline void* Heap::allocateObjectOfType(size_t bytes) 203 230 { 204 231 // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject. … … 211 238 212 239 template<typename ClassType> 213 MarkedSpace::Subspace& Heap::subspaceForObjectOfType()240 inline MarkedSpace::Subspace& Heap::subspaceForObjectOfType() 214 241 { 215 242 // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject. … … 222 249 223 250 template<typename ClassType> 224 MarkedAllocator&Heap::allocatorForObjectOfType(size_t bytes)251 inline MarkedAllocator* Heap::allocatorForObjectOfType(size_t bytes) 225 252 { 226 253 // JSCell::classInfo() expects objects allocated with normal destructor to derive from JSDestructibleObject. 227 254 ASSERT((!ClassType::needsDestruction || (ClassType::StructureFlags & StructureIsImmortal) || std::is_convertible<ClassType, JSDestructibleObject>::value)); 255 256 MarkedAllocator* result; 257 if (ClassType::needsDestruction) 258 result = allocatorForObjectWithDestructor(bytes); 259 else 260 result = allocatorForObjectWithoutDestructor(bytes); 228 261 229 if (ClassType::needsDestruction) 230 return allocatorForObjectWithDestructor(bytes); 231 return allocatorForObjectWithoutDestructor(bytes); 262 ASSERT(result || !ClassType::info()->isSubClassOf(JSCallee::info())); 263 return result; 264 } 265 266 inline void* Heap::allocateAuxiliary(JSCell* intendedOwner, size_t bytes) 267 { 268 void* result = m_objectSpace.allocateAuxiliary(bytes); 269 #if ENABLE(ALLOCATION_LOGGING) 270 dataLogF("JSC GC allocating %lu bytes of auxiliary for %p: %p.\n", bytes, intendedOwner, result); 271 #else 272 UNUSED_PARAM(intendedOwner); 273 #endif 274 return result; 275 } 276 277 inline void* Heap::tryAllocateAuxiliary(JSCell* intendedOwner, size_t bytes) 278 { 279 void* result = m_objectSpace.tryAllocateAuxiliary(bytes); 280 #if ENABLE(ALLOCATION_LOGGING) 281 dataLogF("JSC GC allocating %lu bytes of auxiliary for %p: %p.\n", bytes, intendedOwner, result); 282 #else 283 UNUSED_PARAM(intendedOwner); 284 #endif 285 return result; 286 } 287 288 inline void* Heap::tryReallocateAuxiliary(JSCell* intendedOwner, void* oldBase, size_t oldSize, size_t newSize) 289 { 290 void* newBase = tryAllocateAuxiliary(intendedOwner, newSize); 291 if (!newBase) 292 return nullptr; 293 memcpy(newBase, oldBase, oldSize); 294 return newBase; 232 295 } 233 296 … … 355 418 } 356 419 357 inline bool Heap::isPointerGCObject(TinyBloomFilter filter, MarkedBlockSet& markedBlockSet, void* pointer)358 {359 MarkedBlock* candidate = MarkedBlock::blockFor(pointer);360 if (filter.ruleOut(bitwise_cast<Bits>(candidate))) {361 ASSERT(!candidate || !markedBlockSet.set().contains(candidate));362 return false;363 }364 365 if (!MarkedBlock::isAtomAligned(pointer))366 return false;367 368 if (!markedBlockSet.set().contains(candidate))369 return false;370 371 if (!candidate->isLiveCell(pointer))372 return false;373 374 return true;375 }376 377 inline bool Heap::isValueGCObject(TinyBloomFilter filter, MarkedBlockSet& markedBlockSet, JSValue value)378 {379 if (!value.isCell())380 return false;381 return isPointerGCObject(filter, markedBlockSet, static_cast<void*>(value.asCell()));382 }383 384 420 } // namespace JSC 385 421 -
trunk/Source/JavaScriptCore/heap/HeapOperation.h
r165940 r205462 33 33 } // namespace JSC 34 34 35 namespace WTF { 36 37 class PrintStream; 38 39 void printInternal(PrintStream& out, JSC::HeapOperation); 40 41 } // namespace WTF 42 35 43 #endif // HeapOperation_h -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp
r204466 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 129 129 { 130 130 while (!m_blocksToSweep.isEmpty()) { 131 MarkedBlock* block = m_blocksToSweep.takeLast(); 131 MarkedBlock::Handle* block = m_blocksToSweep.takeLast(); 132 block->setIsOnBlocksToSweep(false); 132 133 133 134 if (!block->needsSweeping()) -
trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h
r197563 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include "HeapTimer.h" 30 #include "MarkedBlock.h" 30 31 #include <wtf/Vector.h> 31 32 … … 56 57 void cancelTimer(); 57 58 58 Vector<MarkedBlock *>& m_blocksToSweep;59 Vector<MarkedBlock::Handle*>& m_blocksToSweep; 59 60 #endif 60 61 }; -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.cpp
r204912 r205462 31 31 #include "IncrementalSweeper.h" 32 32 #include "JSCInlines.h" 33 #include "SuperSampler.h" 33 34 #include "VM.h" 34 35 #include <wtf/CurrentTime.h> … … 36 37 namespace JSC { 37 38 38 static bool isListPagedOut(double deadline, DoublyLinkedList<MarkedBlock>& list) 39 MarkedAllocator::MarkedAllocator(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, const AllocatorAttributes& attributes) 40 : m_currentBlock(0) 41 , m_lastActiveBlock(0) 42 , m_nextBlockToSweep(nullptr) 43 , m_cellSize(static_cast<unsigned>(cellSize)) 44 , m_attributes(attributes) 45 , m_heap(heap) 46 , m_markedSpace(markedSpace) 47 { 48 } 49 50 bool MarkedAllocator::isPagedOut(double deadline) 39 51 { 40 52 unsigned itersSinceLastTimeCheck = 0; 41 MarkedBlock * block = list.head();53 MarkedBlock::Handle* block = m_blockList.begin(); 42 54 while (block) { 43 block = block->next(); 55 block = filterNextBlock(block->next()); 56 if (block) 57 block->flipIfNecessary(); // Forces us to touch the memory of the block, but has no semantic effect. 44 58 ++itersSinceLastTimeCheck; 45 59 if (itersSinceLastTimeCheck >= Heap::s_timeCheckResolution) { … … 53 67 } 54 68 55 bool MarkedAllocator::isPagedOut(double deadline) 56 { 57 if (isListPagedOut(deadline, m_blockList)) 58 return true; 59 return false; 60 } 61 62 void MarkedAllocator::retire(MarkedBlock* block, MarkedBlock::FreeList& freeList) 63 { 64 m_blockList.remove(block); 69 void MarkedAllocator::retire(MarkedBlock::Handle* block) 70 { 71 LockHolder locker(m_lock); // This will be called in parallel during GC. 72 if (block == m_currentBlock) { 73 // This happens when the mutator is running. We finished a full GC and marked too few things 74 // to retire. Then we started allocating in this block. Then a barrier ran, which marked an 75 // object in this block, which put it over the retirement threshold. It's OK to simply do 76 // nothing in that case. 77 return; 78 } 79 if (block == m_lastActiveBlock) { 80 // This can easily happen during marking. It would be easy to handle this case, but it's 81 // just as easy to ignore it. 82 return; 83 } 84 RELEASE_ASSERT(block->isOnList()); 85 if (block == m_nextBlockToSweep) 86 m_nextBlockToSweep = filterNextBlock(block->next()); 87 block->remove(); 65 88 m_retiredBlocks.push(block); 66 block->didRetireBlock(freeList); 67 } 68 69 inline void* MarkedAllocator::tryAllocateHelper(size_t bytes) 70 { 89 } 90 91 MarkedBlock::Handle* MarkedAllocator::filterNextBlock(MarkedBlock::Handle* block) 92 { 93 if (block == m_blockList.end()) 94 return nullptr; 95 return block; 96 } 97 98 void MarkedAllocator::setNextBlockToSweep(MarkedBlock::Handle* block) 99 { 100 m_nextBlockToSweep = filterNextBlock(block); 101 } 102 103 void* MarkedAllocator::tryAllocateWithoutCollectingImpl() 104 { 105 SuperSamplerScope superSamplerScope(false); 106 71 107 if (m_currentBlock) { 72 108 ASSERT(m_currentBlock == m_nextBlockToSweep); 73 109 m_currentBlock->didConsumeFreeList(); 74 m_nextBlockToSweep = m_currentBlock->next(); 75 } 76 77 MarkedBlock* next; 78 for (MarkedBlock*& block = m_nextBlockToSweep; block; block = next) { 79 next = block->next(); 80 81 MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList); 110 setNextBlockToSweep(m_currentBlock->next()); 111 } 112 113 setFreeList(FreeList()); 114 115 RELEASE_ASSERT(m_nextBlockToSweep != m_blockList.end()); 116 117 MarkedBlock::Handle* next; 118 for (MarkedBlock::Handle*& block = m_nextBlockToSweep; block; block = next) { 119 next = filterNextBlock(block->next()); 120 121 // It would be super weird if the blocks we are sweeping have anything allocated during this 122 // cycle. 123 ASSERT(!block->hasAnyNewlyAllocated()); 82 124 83 double utilization = ((double)MarkedBlock::blockSize - (double)freeList.bytes) / (double)MarkedBlock::blockSize; 84 if (utilization >= Options::minMarkedBlockUtilization()) { 85 ASSERT(freeList.bytes || !freeList.head); 86 retire(block, freeList); 125 FreeList freeList = block->sweep(MarkedBlock::Handle::SweepToFreeList); 126 127 // It's possible to stumble on a complete-full block. Marking tries to retire these, but 128 // that algorithm is racy and may forget to do it sometimes. 129 if (freeList.allocationWillFail()) { 130 ASSERT(block->isFreeListed()); 131 block->unsweepWithNoNewlyAllocated(); 132 ASSERT(block->isMarked()); 133 retire(block); 87 134 continue; 88 135 } 89 136 90 if (bytes > block->cellSize()) {91 block->stopAllocating(freeList);92 continue;93 }94 95 137 m_currentBlock = block; 96 m_freeList = freeList;138 setFreeList(freeList); 97 139 break; 98 140 } 99 141 100 if (!m_freeList .head) {142 if (!m_freeList) { 101 143 m_currentBlock = 0; 102 144 return 0; 103 145 } 104 146 105 ASSERT(m_freeList.head); 106 void* head = tryPopFreeList(bytes); 107 ASSERT(head); 147 void* result; 148 if (m_freeList.remaining) { 149 unsigned cellSize = m_cellSize; 150 m_freeList.remaining -= cellSize; 151 result = m_freeList.payloadEnd - m_freeList.remaining - cellSize; 152 } else { 153 FreeCell* head = m_freeList.head; 154 m_freeList.head = head->next; 155 result = head; 156 } 157 RELEASE_ASSERT(result); 108 158 m_markedSpace->didAllocateInBlock(m_currentBlock); 109 return head; 110 } 111 112 inline void* MarkedAllocator::tryPopFreeList(size_t bytes) 113 { 114 ASSERT(m_currentBlock); 115 if (bytes > m_currentBlock->cellSize()) 116 return 0; 117 118 MarkedBlock::FreeCell* head = m_freeList.head; 119 m_freeList.head = head->next; 120 return head; 121 } 122 123 inline void* MarkedAllocator::tryAllocate(size_t bytes) 159 return result; 160 } 161 162 inline void* MarkedAllocator::tryAllocateWithoutCollecting() 124 163 { 125 164 ASSERT(!m_heap->isBusy()); 126 165 m_heap->m_operationInProgress = Allocation; 127 void* result = tryAllocate Helper(bytes);166 void* result = tryAllocateWithoutCollectingImpl(); 128 167 129 168 m_heap->m_operationInProgress = NoOperation; … … 147 186 } 148 187 149 void* MarkedAllocator::allocateSlowCase(size_t bytes) 150 { 188 void* MarkedAllocator::allocateSlowCase() 189 { 190 bool crashOnFailure = true; 191 return allocateSlowCaseImpl(crashOnFailure); 192 } 193 194 void* MarkedAllocator::tryAllocateSlowCase() 195 { 196 bool crashOnFailure = false; 197 return allocateSlowCaseImpl(crashOnFailure); 198 } 199 200 void* MarkedAllocator::allocateSlowCaseImpl(bool crashOnFailure) 201 { 202 SuperSamplerScope superSamplerScope(false); 151 203 ASSERT(m_heap->vm()->currentThreadIsHoldingAPILock()); 152 204 doTestCollectionsIfNeeded(); 153 205 154 206 ASSERT(!m_markedSpace->isIterating()); 155 ASSERT(!m_freeList.head); 156 m_heap->didAllocate(m_freeList.bytes); 157 158 void* result = tryAllocate(bytes); 207 m_heap->didAllocate(m_freeList.originalSize); 208 209 void* result = tryAllocateWithoutCollecting(); 159 210 160 211 if (LIKELY(result != 0)) … … 162 213 163 214 if (m_heap->collectIfNecessaryOrDefer()) { 164 result = tryAllocate (bytes);215 result = tryAllocateWithoutCollecting(); 165 216 if (result) 166 217 return result; … … 169 220 ASSERT(!m_heap->shouldCollect()); 170 221 171 MarkedBlock* block = allocateBlock(bytes); 172 ASSERT(block); 222 MarkedBlock::Handle* block = tryAllocateBlock(); 223 if (!block) { 224 if (crashOnFailure) 225 RELEASE_ASSERT_NOT_REACHED(); 226 else 227 return nullptr; 228 } 173 229 addBlock(block); 174 230 175 result = tryAllocate (bytes);231 result = tryAllocateWithoutCollecting(); 176 232 ASSERT(result); 177 233 return result; 178 234 } 179 235 180 MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes) 236 static size_t blockHeaderSize() 237 { 238 return WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(sizeof(MarkedBlock)); 239 } 240 241 size_t MarkedAllocator::blockSizeForBytes(size_t bytes) 181 242 { 182 243 size_t minBlockSize = MarkedBlock::blockSize; 183 size_t minAllocationSize = WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(sizeof(MarkedBlock)) + WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);244 size_t minAllocationSize = blockHeaderSize() + WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes); 184 245 minAllocationSize = WTF::roundUpToMultipleOf(WTF::pageSize(), minAllocationSize); 185 size_t blockSize = std::max(minBlockSize, minAllocationSize); 186 187 size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes); 188 189 return MarkedBlock::create(*m_heap, this, blockSize, cellSize, m_attributes); 190 } 191 192 void MarkedAllocator::addBlock(MarkedBlock* block) 246 return std::max(minBlockSize, minAllocationSize); 247 } 248 249 MarkedBlock::Handle* MarkedAllocator::tryAllocateBlock() 250 { 251 SuperSamplerScope superSamplerScope(false); 252 return MarkedBlock::tryCreate(*m_heap, this, m_cellSize, m_attributes); 253 } 254 255 void MarkedAllocator::addBlock(MarkedBlock::Handle* block) 193 256 { 194 257 ASSERT(!m_currentBlock); 195 ASSERT(!m_freeList .head);258 ASSERT(!m_freeList); 196 259 197 260 m_blockList.append(block); 198 m_nextBlockToSweep = block;261 setNextBlockToSweep(block); 199 262 m_markedSpace->didAddBlock(block); 200 263 } 201 264 202 void MarkedAllocator::removeBlock(MarkedBlock * block)265 void MarkedAllocator::removeBlock(MarkedBlock::Handle* block) 203 266 { 204 267 if (m_currentBlock == block) { 205 m_currentBlock = m_currentBlock->next();206 m_freeList = MarkedBlock::FreeList();268 m_currentBlock = filterNextBlock(m_currentBlock->next()); 269 setFreeList(FreeList()); 207 270 } 208 271 if (m_nextBlockToSweep == block) 209 m_nextBlockToSweep = m_nextBlockToSweep->next();272 setNextBlockToSweep(m_nextBlockToSweep->next()); 210 273 211 274 block->willRemoveBlock(); … … 213 276 } 214 277 278 void MarkedAllocator::stopAllocating() 279 { 280 if (m_heap->operationInProgress() == FullCollection) 281 m_blockList.takeFrom(m_retiredBlocks); 282 283 ASSERT(!m_lastActiveBlock); 284 if (!m_currentBlock) { 285 ASSERT(!m_freeList); 286 return; 287 } 288 289 m_currentBlock->stopAllocating(m_freeList); 290 m_lastActiveBlock = m_currentBlock; 291 m_currentBlock = 0; 292 m_freeList = FreeList(); 293 } 294 215 295 void MarkedAllocator::reset() 216 296 { 217 297 m_lastActiveBlock = 0; 218 298 m_currentBlock = 0; 219 m_freeList = MarkedBlock::FreeList(); 220 if (m_heap->operationInProgress() == FullCollection) 221 m_blockList.append(m_retiredBlocks); 222 223 m_nextBlockToSweep = m_blockList.head(); 299 setFreeList(FreeList()); 300 301 setNextBlockToSweep(m_blockList.begin()); 224 302 225 303 if (UNLIKELY(Options::useImmortalObjects())) { 226 MarkedBlock* next; 227 for (MarkedBlock*& block = m_nextBlockToSweep; block; block = next) { 228 next = block->next(); 229 230 MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList); 231 retire(block, freeList); 304 MarkedBlock::Handle* next; 305 for (MarkedBlock::Handle*& block = m_nextBlockToSweep; block; block = next) { 306 next = filterNextBlock(block->next()); 307 308 FreeList freeList = block->sweep(MarkedBlock::Handle::SweepToFreeList); 309 block->zap(freeList); 310 retire(block); 232 311 } 233 312 } … … 236 315 void MarkedAllocator::lastChanceToFinalize() 237 316 { 238 m_blockList. append(m_retiredBlocks);317 m_blockList.takeFrom(m_retiredBlocks); 239 318 forEachBlock( 240 [&] (MarkedBlock * block) {319 [&] (MarkedBlock::Handle* block) { 241 320 block->lastChanceToFinalize(); 242 321 }); 243 322 } 244 323 324 void MarkedAllocator::setFreeList(const FreeList& freeList) 325 { 326 m_freeList = freeList; 327 } 328 245 329 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/MarkedAllocator.h
r204912 r205462 28 28 29 29 #include "AllocatorAttributes.h" 30 #include "FreeList.h" 30 31 #include "MarkedBlock.h" 31 #include <wtf/ DoublyLinkedList.h>32 #include <wtf/SentinelLinkedList.h> 32 33 33 34 namespace JSC { … … 41 42 42 43 public: 43 static ptrdiff_t offsetOfFreeListHead(); 44 static ptrdiff_t offsetOfFreeList(); 45 static ptrdiff_t offsetOfCellSize(); 44 46 45 MarkedAllocator( );47 MarkedAllocator(Heap*, MarkedSpace*, size_t cellSize, const AllocatorAttributes&); 46 48 void lastChanceToFinalize(); 47 49 void reset(); … … 53 55 DestructionMode destruction() const { return m_attributes.destruction; } 54 56 HeapCell::Kind cellKind() const { return m_attributes.cellKind; } 55 void* allocate(size_t); 57 void* allocate(); 58 void* tryAllocate(); 56 59 Heap* heap() { return m_heap; } 57 MarkedBlock * takeLastActiveBlock()60 MarkedBlock::Handle* takeLastActiveBlock() 58 61 { 59 MarkedBlock * block = m_lastActiveBlock;62 MarkedBlock::Handle* block = m_lastActiveBlock; 60 63 m_lastActiveBlock = 0; 61 64 return block; … … 64 67 template<typename Functor> void forEachBlock(const Functor&); 65 68 66 void addBlock(MarkedBlock*); 67 void removeBlock(MarkedBlock*); 68 void init(Heap*, MarkedSpace*, size_t cellSize, const AllocatorAttributes&); 69 void addBlock(MarkedBlock::Handle*); 70 void removeBlock(MarkedBlock::Handle*); 69 71 70 72 bool isPagedOut(double deadline); 73 74 static size_t blockSizeForBytes(size_t); 71 75 72 76 private: 73 JS_EXPORT_PRIVATE void* allocateSlowCase(size_t); 74 void* tryAllocate(size_t); 75 void* tryAllocateHelper(size_t); 76 void* tryPopFreeList(size_t); 77 MarkedBlock* allocateBlock(size_t); 77 friend class MarkedBlock; 78 79 JS_EXPORT_PRIVATE void* allocateSlowCase(); 80 JS_EXPORT_PRIVATE void* tryAllocateSlowCase(); 81 void* allocateSlowCaseImpl(bool crashOnFailure); 82 void* tryAllocateWithoutCollecting(); 83 void* tryAllocateWithoutCollectingImpl(); 84 MarkedBlock::Handle* tryAllocateBlock(); 78 85 ALWAYS_INLINE void doTestCollectionsIfNeeded(); 79 void retire(MarkedBlock *, MarkedBlock::FreeList&);86 void retire(MarkedBlock::Handle*); 80 87 81 MarkedBlock::FreeList m_freeList; 82 MarkedBlock* m_currentBlock; 83 MarkedBlock* m_lastActiveBlock; 84 MarkedBlock* m_nextBlockToSweep; 85 DoublyLinkedList<MarkedBlock> m_blockList; 86 DoublyLinkedList<MarkedBlock> m_retiredBlocks; 87 size_t m_cellSize; 88 void setFreeList(const FreeList&); 89 90 MarkedBlock::Handle* filterNextBlock(MarkedBlock::Handle*); 91 void setNextBlockToSweep(MarkedBlock::Handle*); 92 93 FreeList m_freeList; 94 MarkedBlock::Handle* m_currentBlock; 95 MarkedBlock::Handle* m_lastActiveBlock; 96 MarkedBlock::Handle* m_nextBlockToSweep; 97 SentinelLinkedList<MarkedBlock::Handle, BasicRawSentinelNode<MarkedBlock::Handle>> m_blockList; 98 SentinelLinkedList<MarkedBlock::Handle, BasicRawSentinelNode<MarkedBlock::Handle>> m_retiredBlocks; 99 Lock m_lock; 100 unsigned m_cellSize; 88 101 AllocatorAttributes m_attributes; 89 102 Heap* m_heap; … … 91 104 }; 92 105 93 inline ptrdiff_t MarkedAllocator::offsetOfFreeList Head()106 inline ptrdiff_t MarkedAllocator::offsetOfFreeList() 94 107 { 95 return OBJECT_OFFSETOF(MarkedAllocator, m_freeList) + OBJECT_OFFSETOF(MarkedBlock::FreeList, head);108 return OBJECT_OFFSETOF(MarkedAllocator, m_freeList); 96 109 } 97 110 98 inline MarkedAllocator::MarkedAllocator() 99 : m_currentBlock(0) 100 , m_lastActiveBlock(0) 101 , m_nextBlockToSweep(0) 102 , m_cellSize(0) 103 , m_heap(0) 104 , m_markedSpace(0) 111 inline ptrdiff_t MarkedAllocator::offsetOfCellSize() 105 112 { 113 return OBJECT_OFFSETOF(MarkedAllocator, m_cellSize); 106 114 } 107 115 108 inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, const AllocatorAttributes& attributes)116 ALWAYS_INLINE void* MarkedAllocator::tryAllocate() 109 117 { 110 m_heap = heap; 111 m_markedSpace = markedSpace; 112 m_cellSize = cellSize; 113 m_attributes = attributes; 114 } 115 116 inline void* MarkedAllocator::allocate(size_t bytes) 117 { 118 MarkedBlock::FreeCell* head = m_freeList.head; 119 if (UNLIKELY(!head)) { 120 void* result = allocateSlowCase(bytes); 121 #ifndef NDEBUG 122 memset(result, 0xCD, bytes); 123 #endif 124 return result; 118 unsigned remaining = m_freeList.remaining; 119 if (remaining) { 120 unsigned cellSize = m_cellSize; 121 remaining -= cellSize; 122 m_freeList.remaining = remaining; 123 return m_freeList.payloadEnd - remaining - cellSize; 125 124 } 126 125 126 FreeCell* head = m_freeList.head; 127 if (UNLIKELY(!head)) 128 return tryAllocateSlowCase(); 129 127 130 m_freeList.head = head->next; 128 #ifndef NDEBUG129 memset(head, 0xCD, bytes);130 #endif131 131 return head; 132 132 } 133 133 134 inline void MarkedAllocator::stopAllocating()134 ALWAYS_INLINE void* MarkedAllocator::allocate() 135 135 { 136 ASSERT(!m_lastActiveBlock); 137 if (!m_currentBlock) { 138 ASSERT(!m_freeList.head); 139 return; 136 unsigned remaining = m_freeList.remaining; 137 if (remaining) { 138 unsigned cellSize = m_cellSize; 139 remaining -= cellSize; 140 m_freeList.remaining = remaining; 141 return m_freeList.payloadEnd - remaining - cellSize; 140 142 } 141 143 142 m_currentBlock->stopAllocating(m_freeList); 143 m_lastActiveBlock = m_currentBlock; 144 m_currentBlock = 0; 145 m_freeList = MarkedBlock::FreeList(); 144 FreeCell* head = m_freeList.head; 145 if (UNLIKELY(!head)) 146 return allocateSlowCase(); 147 148 m_freeList.head = head->next; 149 return head; 146 150 } 147 151 … … 158 162 template <typename Functor> inline void MarkedAllocator::forEachBlock(const Functor& functor) 159 163 { 160 MarkedBlock* next; 161 for (MarkedBlock* block = m_blockList.head(); block; block = next) { 162 next = block->next(); 163 functor(block); 164 } 165 166 for (MarkedBlock* block = m_retiredBlocks.head(); block; block = next) { 167 next = block->next(); 168 functor(block); 169 } 164 m_blockList.forEach(functor); 165 m_retiredBlocks.forEach(functor); 170 166 } 171 167 -
trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp
r204912 r205462 30 30 #include "JSDestructibleObject.h" 31 31 #include "JSCInlines.h" 32 #include "SuperSampler.h" 32 33 33 34 namespace JSC { … … 36 37 static size_t balance; 37 38 38 MarkedBlock * MarkedBlock::create(Heap& heap, MarkedAllocator* allocator, size_t capacity, size_t cellSize, const AllocatorAttributes& attributes)39 MarkedBlock::Handle* MarkedBlock::tryCreate(Heap& heap, MarkedAllocator* allocator, size_t cellSize, const AllocatorAttributes& attributes) 39 40 { 40 41 if (computeBalance) { … … 43 44 dataLog("MarkedBlock Balance: ", balance, "\n"); 44 45 } 45 MarkedBlock* block = new (NotNull, fastAlignedMalloc(blockSize, capacity)) MarkedBlock(allocator, capacity, cellSize, attributes); 46 heap.didAllocateBlock(capacity); 47 return block; 48 } 49 50 void MarkedBlock::destroy(Heap& heap, MarkedBlock* block) 51 { 46 void* blockSpace = tryFastAlignedMalloc(blockSize, blockSize); 47 if (!blockSpace) 48 return nullptr; 49 if (scribbleFreeCells()) 50 scribble(blockSpace, blockSize); 51 return new Handle(heap, allocator, cellSize, attributes, blockSpace); 52 } 53 54 MarkedBlock::Handle::Handle(Heap& heap, MarkedAllocator* allocator, size_t cellSize, const AllocatorAttributes& attributes, void* blockSpace) 55 : m_atomsPerCell((cellSize + atomSize - 1) / atomSize) 56 , m_endAtom(atomsPerBlock - m_atomsPerCell + 1) 57 , m_attributes(attributes) 58 , m_state(New) // All cells start out unmarked. 59 , m_allocator(allocator) 60 , m_weakSet(allocator->heap()->vm(), CellContainer()) 61 { 62 m_block = new (NotNull, blockSpace) MarkedBlock(*heap.vm(), *this); 63 64 m_weakSet.setContainer(*m_block); 65 66 heap.didAllocateBlock(blockSize); 67 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 68 ASSERT(allocator); 69 if (m_attributes.cellKind != HeapCell::JSCell) 70 RELEASE_ASSERT(m_attributes.destruction == DoesNotNeedDestruction); 71 } 72 73 MarkedBlock::Handle::~Handle() 74 { 75 Heap& heap = *this->heap(); 52 76 if (computeBalance) { 53 77 balance--; … … 55 79 dataLog("MarkedBlock Balance: ", balance, "\n"); 56 80 } 57 size_t capacity = block->capacity(); 58 block->~MarkedBlock(); 59 fastAlignedFree(block); 60 heap.didFreeBlock(capacity); 61 } 62 63 MarkedBlock::MarkedBlock(MarkedAllocator* allocator, size_t capacity, size_t cellSize, const AllocatorAttributes& attributes) 64 : DoublyLinkedListNode<MarkedBlock>() 65 , m_atomsPerCell((cellSize + atomSize - 1) / atomSize) 66 , m_endAtom((allocator->cellSize() ? atomsPerBlock - m_atomsPerCell : firstAtom()) + 1) 67 , m_capacity(capacity) 68 , m_attributes(attributes) 69 , m_allocator(allocator) 70 , m_state(New) // All cells start out unmarked. 71 , m_weakSet(allocator->heap()->vm(), *this) 72 { 73 ASSERT(allocator); 74 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 75 if (m_attributes.cellKind != HeapCell::JSCell) 76 RELEASE_ASSERT(m_attributes.destruction == DoesNotNeedDestruction); 77 } 78 79 inline void MarkedBlock::callDestructor(HeapCell* cell) 80 { 81 // A previous eager sweep may already have run cell's destructor. 82 if (cell->isZapped()) 83 return; 84 85 JSCell* jsCell = static_cast<JSCell*>(cell); 86 87 ASSERT(jsCell->structureID()); 88 if (jsCell->inlineTypeFlags() & StructureIsImmortal) 89 jsCell->structure(*vm())->classInfo()->methodTable.destroy(jsCell); 90 else 91 jsCast<JSDestructibleObject*>(jsCell)->classInfo()->methodTable.destroy(jsCell); 92 cell->zap(); 93 } 94 95 template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, bool callDestructors> 96 MarkedBlock::FreeList MarkedBlock::specializedSweep() 97 { 98 ASSERT(blockState != Allocated && blockState != FreeListed); 99 ASSERT(!(!callDestructors && sweepMode == SweepOnly)); 81 m_block->~MarkedBlock(); 82 fastAlignedFree(m_block); 83 heap.didFreeBlock(blockSize); 84 } 85 86 MarkedBlock::MarkedBlock(VM& vm, Handle& handle) 87 : m_needsDestruction(handle.needsDestruction()) 88 , m_handle(handle) 89 , m_vm(&vm) 90 , m_version(vm.heap.objectSpace().version()) 91 { 92 unsigned cellsPerBlock = MarkedSpace::blockPayload / handle.cellSize(); 93 double markCountBias = -(Options::minMarkedBlockUtilization() * cellsPerBlock); 94 95 // The mark count bias should be comfortably within this range. 96 RELEASE_ASSERT(markCountBias > static_cast<double>(std::numeric_limits<int16_t>::min())); 97 RELEASE_ASSERT(markCountBias < 0); 98 99 m_markCountBias = static_cast<int16_t>(markCountBias); 100 101 m_biasedMarkCount = m_markCountBias; // This means we haven't marked anything yet. 102 } 103 104 template<MarkedBlock::BlockState blockState, MarkedBlock::Handle::SweepMode sweepMode, DestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode, MarkedBlock::Handle::NewlyAllocatedMode newlyAllocatedMode> 105 FreeList MarkedBlock::Handle::specializedSweep() 106 { 107 SuperSamplerScope superSamplerScope(false); 108 ASSERT(blockState == New || blockState == Marked); 109 ASSERT(!(destructionMode == DoesNotNeedDestruction && sweepMode == SweepOnly)); 110 111 assertFlipped(); 112 MarkedBlock& block = this->block(); 113 114 bool isNewBlock = blockState == New; 115 bool isEmptyBlock = !block.hasAnyMarked() 116 && newlyAllocatedMode == DoesNotHaveNewlyAllocated 117 && destructionMode == DoesNotNeedDestruction; 118 if (Options::useBumpAllocator() && (isNewBlock || isEmptyBlock)) { 119 ASSERT(block.m_marks.isEmpty()); 120 121 char* startOfLastCell = static_cast<char*>(cellAlign(block.atoms() + m_endAtom - 1)); 122 char* payloadEnd = startOfLastCell + cellSize(); 123 RELEASE_ASSERT(payloadEnd - MarkedBlock::blockSize <= bitwise_cast<char*>(&block)); 124 char* payloadBegin = bitwise_cast<char*>(block.atoms() + firstAtom()); 125 if (scribbleMode == Scribble) 126 scribble(payloadBegin, payloadEnd - payloadBegin); 127 m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Marked); 128 FreeList result = FreeList::bump(payloadEnd, payloadEnd - payloadBegin); 129 if (false) 130 dataLog("Quickly swept block ", RawPointer(this), " with cell size ", cellSize(), " and attributes ", m_attributes, ": ", result, "\n"); 131 return result; 132 } 100 133 101 134 // This produces a free list that is ordered in reverse through the block. … … 105 138 size_t count = 0; 106 139 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 107 if (blockState == Marked && (m_marks.get(i) || (m_newlyAllocated && m_newlyAllocated->get(i)))) 140 if (blockState == Marked 141 && (block.m_marks.get(i) 142 || (newlyAllocatedMode == HasNewlyAllocated && m_newlyAllocated->get(i)))) 108 143 continue; 109 144 110 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(& atoms()[i]);111 112 if ( callDestructors&& blockState != New)113 callDestructor(cell);145 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&block.atoms()[i]); 146 147 if (destructionMode == NeedsDestruction && blockState != New) 148 static_cast<JSCell*>(cell)->callDestructor(*vm()); 114 149 115 150 if (sweepMode == SweepToFreeList) { 116 151 FreeCell* freeCell = reinterpret_cast<FreeCell*>(cell); 152 if (scribbleMode == Scribble) 153 scribble(freeCell, cellSize()); 117 154 freeCell->next = head; 118 155 head = freeCell; … … 123 160 // We only want to discard the newlyAllocated bits if we're creating a FreeList, 124 161 // otherwise we would lose information on what's currently alive. 125 if (sweepMode == SweepToFreeList && m_newlyAllocated)162 if (sweepMode == SweepToFreeList && newlyAllocatedMode == HasNewlyAllocated) 126 163 m_newlyAllocated = nullptr; 127 164 128 m_state = ((sweepMode == SweepToFreeList) ? FreeListed : Marked); 129 return FreeList(head, count * cellSize()); 130 } 131 132 MarkedBlock::FreeList MarkedBlock::sweep(SweepMode sweepMode) 133 { 165 FreeList result = FreeList::list(head, count * cellSize()); 166 m_state = (sweepMode == SweepToFreeList ? FreeListed : Marked); 167 if (false) 168 dataLog("Slowly swept block ", RawPointer(&block), " with cell size ", cellSize(), " and attributes ", m_attributes, ": ", result, "\n"); 169 return result; 170 } 171 172 FreeList MarkedBlock::Handle::sweep(SweepMode sweepMode) 173 { 174 flipIfNecessary(); 175 134 176 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 135 177 … … 140 182 141 183 if (m_attributes.destruction == NeedsDestruction) 142 return sweepHelper<true>(sweepMode); 143 return sweepHelper<false>(sweepMode); 144 } 145 146 template<bool callDestructors> 147 MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode) 184 return sweepHelperSelectScribbleMode<NeedsDestruction>(sweepMode); 185 return sweepHelperSelectScribbleMode<DoesNotNeedDestruction>(sweepMode); 186 } 187 188 template<DestructionMode destructionMode> 189 FreeList MarkedBlock::Handle::sweepHelperSelectScribbleMode(SweepMode sweepMode) 190 { 191 if (scribbleFreeCells()) 192 return sweepHelperSelectStateAndSweepMode<destructionMode, Scribble>(sweepMode); 193 return sweepHelperSelectStateAndSweepMode<destructionMode, DontScribble>(sweepMode); 194 } 195 196 template<DestructionMode destructionMode, MarkedBlock::Handle::ScribbleMode scribbleMode> 197 FreeList MarkedBlock::Handle::sweepHelperSelectStateAndSweepMode(SweepMode sweepMode) 148 198 { 149 199 switch (m_state) { 150 200 case New: 151 201 ASSERT(sweepMode == SweepToFreeList); 152 return specializedSweep<New, SweepToFreeList, callDestructors>();202 return specializedSweep<New, SweepToFreeList, destructionMode, scribbleMode, DoesNotHaveNewlyAllocated>(); 153 203 case FreeListed: 154 204 // Happens when a block transitions to fully allocated. 155 205 ASSERT(sweepMode == SweepToFreeList); 156 206 return FreeList(); 157 case Retired:158 207 case Allocated: 159 208 RELEASE_ASSERT_NOT_REACHED(); 160 209 return FreeList(); 161 210 case Marked: 162 return sweepMode == SweepToFreeList 163 ? specializedSweep<Marked, SweepToFreeList, callDestructors>() 164 : specializedSweep<Marked, SweepOnly, callDestructors>(); 211 if (m_newlyAllocated) { 212 return sweepMode == SweepToFreeList 213 ? specializedSweep<Marked, SweepToFreeList, destructionMode, scribbleMode, HasNewlyAllocated>() 214 : specializedSweep<Marked, SweepOnly, destructionMode, scribbleMode, HasNewlyAllocated>(); 215 } else { 216 return sweepMode == SweepToFreeList 217 ? specializedSweep<Marked, SweepToFreeList, destructionMode, scribbleMode, DoesNotHaveNewlyAllocated>() 218 : specializedSweep<Marked, SweepOnly, destructionMode, scribbleMode, DoesNotHaveNewlyAllocated>(); 219 } 165 220 } 166 221 RELEASE_ASSERT_NOT_REACHED(); … … 168 223 } 169 224 225 void MarkedBlock::Handle::unsweepWithNoNewlyAllocated() 226 { 227 flipIfNecessary(); 228 229 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 230 231 RELEASE_ASSERT(m_state == FreeListed); 232 m_state = Marked; 233 } 234 170 235 class SetNewlyAllocatedFunctor : public MarkedBlock::VoidFunctor { 171 236 public: 172 SetNewlyAllocatedFunctor(MarkedBlock * block)237 SetNewlyAllocatedFunctor(MarkedBlock::Handle* block) 173 238 : m_block(block) 174 239 { … … 177 242 IterationStatus operator()(HeapCell* cell, HeapCell::Kind) const 178 243 { 179 ASSERT(MarkedBlock::blockFor(cell) == m_block);244 ASSERT(MarkedBlock::blockFor(cell) == &m_block->block()); 180 245 m_block->setNewlyAllocated(cell); 181 246 return IterationStatus::Continue; … … 183 248 184 249 private: 185 MarkedBlock * m_block;250 MarkedBlock::Handle* m_block; 186 251 }; 187 252 188 void MarkedBlock:: stopAllocating(const FreeList& freeList)189 { 190 HEAP_LOG_BLOCK_STATE_TRANSITION(this);191 FreeCell* head = freeList.head;253 void MarkedBlock::Handle::stopAllocating(const FreeList& freeList) 254 { 255 flipIfNecessary(); 256 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 192 257 193 258 if (m_state == Marked) { 194 // If the block is in the Marked state then we know that: 195 // 1) It was not used for allocation during the previous allocation cycle. 196 // 2) It may have dead objects, and we only know them to be dead by the 197 // fact that their mark bits are unset. 259 // If the block is in the Marked state then we know that one of these 260 // conditions holds: 261 // 262 // - It was not used for allocation during the previous allocation cycle. 263 // It may have dead objects, and we only know them to be dead by the 264 // fact that their mark bits are unset. 265 // 266 // - Someone had already done stopAllocating(), for example because of 267 // heap iteration, and they had already 198 268 // Hence if the block is Marked we need to leave it Marked. 199 200 ASSERT(!head); 269 ASSERT(freeList.allocationWillFail()); 201 270 return; 202 271 } 203 272 204 273 ASSERT(m_state == FreeListed); 205 274 … … 214 283 forEachCell(functor); 215 284 216 FreeCell* next;217 for (FreeCell* current = head; current; current = next) {218 next = current->next;219 if (m_attributes.destruction == NeedsDestruction)220 reinterpret_cast<HeapCell*>(current)->zap();221 clearNewlyAllocated(current);222 }285 forEachFreeCell( 286 freeList, 287 [&] (HeapCell* cell) { 288 if (m_attributes.destruction == NeedsDestruction) 289 cell->zap(); 290 clearNewlyAllocated(cell); 291 }); 223 292 224 293 m_state = Marked; 225 294 } 226 295 227 void MarkedBlock::clearMarks() 228 { 229 if (heap()->operationInProgress() == JSC::EdenCollection) 230 this->clearMarksWithCollectionType<EdenCollection>(); 231 else 232 this->clearMarksWithCollectionType<FullCollection>(); 233 } 234 235 template <HeapOperation collectionType> 236 void MarkedBlock::clearMarksWithCollectionType() 237 { 238 ASSERT(collectionType == FullCollection || collectionType == EdenCollection); 239 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 240 241 ASSERT(m_state != New && m_state != FreeListed); 242 if (collectionType == FullCollection) { 243 m_marks.clearAll(); 244 // This will become true at the end of the mark phase. We set it now to 245 // avoid an extra pass to do so later. 246 m_state = Marked; 247 return; 248 } 249 250 ASSERT(collectionType == EdenCollection); 251 // If a block was retired then there's no way an EdenCollection can un-retire it. 252 if (m_state != Retired) 253 m_state = Marked; 254 } 255 256 void MarkedBlock::lastChanceToFinalize() 257 { 296 void MarkedBlock::Handle::lastChanceToFinalize() 297 { 298 m_block->clearMarks(); 258 299 m_weakSet.lastChanceToFinalize(); 259 300 260 301 clearNewlyAllocated(); 261 clearMarksWithCollectionType<FullCollection>();262 302 sweep(); 263 303 } 264 304 265 MarkedBlock::FreeList MarkedBlock::resumeAllocating() 266 { 305 FreeList MarkedBlock::Handle::resumeAllocating() 306 { 307 flipIfNecessary(); 267 308 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 268 309 … … 275 316 } 276 317 277 // Re-create our free list from before stopping allocation. 318 // Re-create our free list from before stopping allocation. Note that this may return an empty 319 // freelist, in which case the block will still be Marked! 278 320 return sweep(SweepToFreeList); 279 321 } 280 322 281 void MarkedBlock::didRetireBlock(const FreeList& freeList) 282 { 283 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 284 FreeCell* head = freeList.head; 285 286 // Currently we don't notify the Heap that we're giving up on this block. 287 // The Heap might be able to make a better decision about how many bytes should 288 // be allocated before the next collection if it knew about this retired block. 289 // On the other hand we'll waste at most 10% of our Heap space between FullCollections 290 // and only under heavy fragmentation. 291 292 // We need to zap the free list when retiring a block so that we don't try to destroy 293 // previously destroyed objects when we re-sweep the block in the future. 294 FreeCell* next; 295 for (FreeCell* current = head; current; current = next) { 296 next = current->next; 297 if (m_attributes.destruction == NeedsDestruction) 298 reinterpret_cast<HeapCell*>(current)->zap(); 299 } 300 323 void MarkedBlock::Handle::zap(const FreeList& freeList) 324 { 325 forEachFreeCell( 326 freeList, 327 [&] (HeapCell* cell) { 328 if (m_attributes.destruction == NeedsDestruction) 329 cell->zap(); 330 }); 331 } 332 333 template<typename Func> 334 void MarkedBlock::Handle::forEachFreeCell(const FreeList& freeList, const Func& func) 335 { 336 if (freeList.remaining) { 337 for (unsigned remaining = freeList.remaining; remaining; remaining -= cellSize()) 338 func(bitwise_cast<HeapCell*>(freeList.payloadEnd - remaining)); 339 } else { 340 for (FreeCell* current = freeList.head; current;) { 341 FreeCell* next = current->next; 342 func(bitwise_cast<HeapCell*>(current)); 343 current = next; 344 } 345 } 346 } 347 348 void MarkedBlock::flipIfNecessary() 349 { 350 flipIfNecessary(vm()->heap.objectSpace().version()); 351 } 352 353 void MarkedBlock::Handle::flipIfNecessary() 354 { 355 block().flipIfNecessary(); 356 } 357 358 void MarkedBlock::flipIfNecessarySlow() 359 { 360 ASSERT(m_version != vm()->heap.objectSpace().version()); 361 clearMarks(); 362 } 363 364 void MarkedBlock::flipIfNecessaryConcurrentlySlow() 365 { 366 LockHolder locker(m_lock); 367 if (m_version != vm()->heap.objectSpace().version()) 368 clearMarks(); 369 } 370 371 void MarkedBlock::clearMarks() 372 { 373 m_marks.clearAll(); 374 clearHasAnyMarked(); 375 // This will become true at the end of the mark phase. We set it now to 376 // avoid an extra pass to do so later. 377 handle().m_state = Marked; 378 WTF::storeStoreFence(); 379 m_version = vm()->heap.objectSpace().version(); 380 } 381 382 #if !ASSERT_DISABLED 383 void MarkedBlock::assertFlipped() 384 { 385 ASSERT(m_version == vm()->heap.objectSpace().version()); 386 } 387 #endif // !ASSERT_DISABLED 388 389 bool MarkedBlock::needsFlip() 390 { 391 return vm()->heap.objectSpace().version() != m_version; 392 } 393 394 bool MarkedBlock::Handle::needsFlip() 395 { 396 return m_block->needsFlip(); 397 } 398 399 void MarkedBlock::Handle::willRemoveBlock() 400 { 401 flipIfNecessary(); 402 } 403 404 void MarkedBlock::Handle::didConsumeFreeList() 405 { 406 flipIfNecessary(); 407 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 408 301 409 ASSERT(m_state == FreeListed); 302 m_state = Retired; 410 411 m_state = Allocated; 412 } 413 414 size_t MarkedBlock::markCount() 415 { 416 flipIfNecessary(); 417 return m_marks.count(); 418 } 419 420 bool MarkedBlock::Handle::isEmpty() 421 { 422 flipIfNecessary(); 423 return m_state == Marked && !block().hasAnyMarked() && m_weakSet.isEmpty() && (!m_newlyAllocated || m_newlyAllocated->isEmpty()); 424 } 425 426 void MarkedBlock::clearHasAnyMarked() 427 { 428 m_biasedMarkCount = m_markCountBias; 429 } 430 431 void MarkedBlock::noteMarkedSlow() 432 { 433 handle().m_allocator->retire(&handle()); 303 434 } 304 435 305 436 } // namespace JSC 437 438 namespace WTF { 439 440 using namespace JSC; 441 442 void printInternal(PrintStream& out, MarkedBlock::BlockState blockState) 443 { 444 switch (blockState) { 445 case MarkedBlock::New: 446 out.print("New"); 447 return; 448 case MarkedBlock::FreeListed: 449 out.print("FreeListed"); 450 return; 451 case MarkedBlock::Allocated: 452 out.print("Allocated"); 453 return; 454 case MarkedBlock::Marked: 455 out.print("Marked"); 456 return; 457 } 458 RELEASE_ASSERT_NOT_REACHED(); 459 } 460 461 } // namespace WTF 462 -
trunk/Source/JavaScriptCore/heap/MarkedBlock.h
r204912 r205462 25 25 #include "AllocatorAttributes.h" 26 26 #include "DestructionMode.h" 27 #include "FreeList.h" 27 28 #include "HeapCell.h" 28 29 #include "HeapOperation.h" … … 35 36 #include <wtf/StdLibExtras.h> 36 37 38 namespace JSC { 39 40 class Heap; 41 class JSCell; 42 class MarkedAllocator; 43 44 typedef uintptr_t Bits; 45 37 46 // Set to log state transitions of blocks. 38 47 #define HEAP_LOG_BLOCK_STATE_TRANSITIONS 0 39 48 40 49 #if HEAP_LOG_BLOCK_STATE_TRANSITIONS 41 #define HEAP_LOG_BLOCK_STATE_TRANSITION( block) do {\42 dataLogF( \43 "%s:%d %s: block %s = %p, %d\n", \44 __FILE__, __LINE__, __FUNCTION__, \45 # block, (block), (block)->m_state);\50 #define HEAP_LOG_BLOCK_STATE_TRANSITION(handle) do { \ 51 dataLogF( \ 52 "%s:%d %s: block %s = %p, %d\n", \ 53 __FILE__, __LINE__, __FUNCTION__, \ 54 #handle, &(handle)->block(), (handle)->m_state); \ 46 55 } while (false) 47 56 #else 48 #define HEAP_LOG_BLOCK_STATE_TRANSITION( block) ((void)0)57 #define HEAP_LOG_BLOCK_STATE_TRANSITION(handle) ((void)0) 49 58 #endif 50 59 51 namespace JSC { 52 53 class Heap; 54 class JSCell; 55 class MarkedAllocator; 56 57 typedef uintptr_t Bits; 58 59 // A marked block is a page-aligned container for heap-allocated objects. 60 // Objects are allocated within cells of the marked block. For a given 61 // marked block, all cells have the same size. Objects smaller than the 62 // cell size may be allocated in the marked block, in which case the 63 // allocation suffers from internal fragmentation: wasted space whose 64 // size is equal to the difference between the cell size and the object 65 // size. 66 67 class MarkedBlock : public DoublyLinkedListNode<MarkedBlock> { 68 friend class WTF::DoublyLinkedListNode<MarkedBlock>; 60 // A marked block is a page-aligned container for heap-allocated objects. 61 // Objects are allocated within cells of the marked block. For a given 62 // marked block, all cells have the same size. Objects smaller than the 63 // cell size may be allocated in the marked block, in which case the 64 // allocation suffers from internal fragmentation: wasted space whose 65 // size is equal to the difference between the cell size and the object 66 // size. 67 68 class MarkedBlock { 69 WTF_MAKE_NONCOPYABLE(MarkedBlock); 70 friend class LLIntOffsetsExtractor; 71 friend struct VerifyMarked; 72 73 public: 74 class Handle; 75 private: 76 friend class Handle; 77 public: 78 enum BlockState : uint8_t { New, FreeListed, Allocated, Marked }; 79 80 static const size_t atomSize = 16; // bytes 81 static const size_t blockSize = 16 * KB; 82 static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two. 83 84 static const size_t atomsPerBlock = blockSize / atomSize; 85 86 static_assert(!(MarkedBlock::atomSize & (MarkedBlock::atomSize - 1)), "MarkedBlock::atomSize must be a power of two."); 87 static_assert(!(MarkedBlock::blockSize & (MarkedBlock::blockSize - 1)), "MarkedBlock::blockSize must be a power of two."); 88 89 struct VoidFunctor { 90 typedef void ReturnType; 91 void returnValue() { } 92 }; 93 94 class CountFunctor { 95 public: 96 typedef size_t ReturnType; 97 98 CountFunctor() : m_count(0) { } 99 void count(size_t count) const { m_count += count; } 100 ReturnType returnValue() const { return m_count; } 101 102 private: 103 // FIXME: This is mutable because we're using a functor rather than C++ lambdas. 104 // https://bugs.webkit.org/show_bug.cgi?id=159644 105 mutable ReturnType m_count; 106 }; 107 108 class Handle : public BasicRawSentinelNode<Handle> { 109 WTF_MAKE_NONCOPYABLE(Handle); 110 WTF_MAKE_FAST_ALLOCATED; 111 friend class DoublyLinkedListNode<Handle>; 69 112 friend class LLIntOffsetsExtractor; 70 friend struct VerifyMarkedOrRetired; 113 friend class MarkedBlock; 114 friend struct VerifyMarked; 71 115 public: 72 static const size_t atomSize = 16; // bytes 73 static const size_t blockSize = 16 * KB; 74 static const size_t blockMask = ~(blockSize - 1); // blockSize must be a power of two. 75 76 static const size_t atomsPerBlock = blockSize / atomSize; 77 78 static_assert(!(MarkedBlock::atomSize & (MarkedBlock::atomSize - 1)), "MarkedBlock::atomSize must be a power of two."); 79 static_assert(!(MarkedBlock::blockSize & (MarkedBlock::blockSize - 1)), "MarkedBlock::blockSize must be a power of two."); 80 81 struct FreeCell { 82 FreeCell* next; 83 }; 84 85 struct FreeList { 86 FreeCell* head; 87 size_t bytes; 88 89 FreeList(); 90 FreeList(FreeCell*, size_t); 91 }; 92 93 struct VoidFunctor { 94 typedef void ReturnType; 95 void returnValue() { } 96 }; 97 98 class CountFunctor { 99 public: 100 typedef size_t ReturnType; 101 102 CountFunctor() : m_count(0) { } 103 void count(size_t count) const { m_count += count; } 104 ReturnType returnValue() const { return m_count; } 105 106 private: 107 // FIXME: This is mutable because we're using a functor rather than C++ lambdas. 108 // https://bugs.webkit.org/show_bug.cgi?id=159644 109 mutable ReturnType m_count; 110 }; 111 112 static MarkedBlock* create(Heap&, MarkedAllocator*, size_t capacity, size_t cellSize, const AllocatorAttributes&); 113 static void destroy(Heap&, MarkedBlock*); 114 115 static bool isAtomAligned(const void*); 116 static MarkedBlock* blockFor(const void*); 117 static size_t firstAtom(); 118 116 117 ~Handle(); 118 119 MarkedBlock& block(); 120 121 void* cellAlign(void*); 122 123 bool isEmpty(); 124 119 125 void lastChanceToFinalize(); 120 126 … … 123 129 VM* vm() const; 124 130 WeakSet& weakSet(); 125 131 126 132 enum SweepMode { SweepOnly, SweepToFreeList }; 127 133 FreeList sweep(SweepMode = SweepOnly); 128 134 135 void unsweepWithNoNewlyAllocated(); 136 137 void zap(const FreeList&); 138 129 139 void shrink(); 130 131 void visitWeakSet(HeapRootVisitor&);140 141 unsigned visitWeakSet(HeapRootVisitor&); 132 142 void reapWeakSet(); 133 143 134 144 // While allocating from a free list, MarkedBlock temporarily has bogus 135 145 // cell liveness data. To restore accurate cell liveness data, call one … … 138 148 void stopAllocating(const FreeList&); 139 149 FreeList resumeAllocating(); // Call this if you canonicalized a block for some non-collection related purpose. 140 150 141 151 // Returns true if the "newly allocated" bitmap was non-null 142 152 // and was successfully cleared and false otherwise. 143 153 bool clearNewlyAllocated(); 144 void clearMarks(); 145 template <HeapOperation collectionType> 146 void clearMarksWithCollectionType(); 147 148 size_t markCount(); 149 bool isEmpty(); 150 154 155 void flipForEdenCollection(); 156 151 157 size_t cellSize(); 152 158 const AllocatorAttributes& attributes() const; … … 154 160 bool needsDestruction() const; 155 161 HeapCell::Kind cellKind() const; 156 162 163 size_t markCount(); 157 164 size_t size(); 158 size_t capacity(); 159 160 bool isMarked(const void*); 161 bool testAndSetMarked(const void*); 165 162 166 bool isLive(const HeapCell*); 163 167 bool isLiveCell(const void*); 164 bool isAtom(const void*);165 168 bool isMarkedOrNewlyAllocated(const HeapCell*); 166 void setMarked(const void*); 167 void clearMarked(const void*); 168 169 169 170 bool isNewlyAllocated(const void*); 170 171 void setNewlyAllocated(const void*); 171 172 void clearNewlyAllocated(const void*); 172 173 174 bool hasAnyNewlyAllocated() const { return !!m_newlyAllocated; } 175 173 176 bool isAllocated() const; 174 bool isMarkedOrRetired() const; 177 bool isMarked() const; 178 bool isFreeListed() const; 175 179 bool needsSweeping() const; 176 void didRetireBlock(const FreeList&);177 180 void willRemoveBlock(); 178 181 … … 180 183 template <typename Functor> IterationStatus forEachLiveCell(const Functor&); 181 184 template <typename Functor> IterationStatus forEachDeadCell(const Functor&); 182 185 186 bool needsFlip(); 187 188 void flipIfNecessaryConcurrently(uint64_t heapVersion); 189 void flipIfNecessary(uint64_t heapVersion); 190 void flipIfNecessary(); 191 192 void assertFlipped(); 193 194 bool isOnBlocksToSweep() const { return m_isOnBlocksToSweep; } 195 void setIsOnBlocksToSweep(bool value) { m_isOnBlocksToSweep = value; } 196 197 BlockState state() const { return m_state; } 198 183 199 private: 184 static const size_t atomAlignmentMask = atomSize - 1; 185 186 // During allocation, we look for available space in free lists in blocks. 187 // If a block's utilization is sufficiently high (i.e. it's almost full), 188 // we want to remove that block as a candidate for allocating to reduce 189 // the likelihood of allocation having to take a slow path. When the 190 // block is in this state, we say that it is "Retired". 191 // 192 // A full GC can take a Retired blocks out of retirement. An eden GC 193 // will simply ignore Retired blocks (i.e. they will not be swept even 194 // if they no longer have live objects). 195 196 enum BlockState { New, FreeListed, Allocated, Marked, Retired }; 197 template<bool callDestructors> FreeList sweepHelper(SweepMode = SweepOnly); 198 199 typedef char Atom[atomSize]; 200 201 MarkedBlock(MarkedAllocator*, size_t capacity, size_t cellSize, const AllocatorAttributes&); 202 Atom* atoms(); 203 size_t atomNumber(const void*); 204 void callDestructor(HeapCell*); 205 template<BlockState, SweepMode, bool callDestructors> FreeList specializedSweep(); 206 207 MarkedBlock* m_prev; 208 MarkedBlock* m_next; 209 200 Handle(Heap&, MarkedAllocator*, size_t cellSize, const AllocatorAttributes&, void*); 201 202 template<DestructionMode> 203 FreeList sweepHelperSelectScribbleMode(SweepMode = SweepOnly); 204 205 enum ScribbleMode { DontScribble, Scribble }; 206 207 template<DestructionMode, ScribbleMode> 208 FreeList sweepHelperSelectStateAndSweepMode(SweepMode = SweepOnly); 209 210 enum NewlyAllocatedMode { HasNewlyAllocated, DoesNotHaveNewlyAllocated }; 211 212 template<BlockState, SweepMode, DestructionMode, ScribbleMode, NewlyAllocatedMode> 213 FreeList specializedSweep(); 214 215 template<typename Func> 216 void forEachFreeCell(const FreeList&, const Func&); 217 218 MarkedBlock::Handle* m_prev; 219 MarkedBlock::Handle* m_next; 220 210 221 size_t m_atomsPerCell; 211 222 size_t m_endAtom; // This is a fuzzy end. Always test for < m_endAtom. 212 WTF::Bitmap<atomsPerBlock, WTF::BitmapAtomic, uint8_t> m_marks;223 213 224 std::unique_ptr<WTF::Bitmap<atomsPerBlock>> m_newlyAllocated; 214 215 size_t m_capacity; 225 216 226 AllocatorAttributes m_attributes; 227 BlockState m_state; 228 bool m_isOnBlocksToSweep { false }; 229 217 230 MarkedAllocator* m_allocator; 218 BlockState m_state;219 231 WeakSet m_weakSet; 232 233 MarkedBlock* m_block; 220 234 }; 221 222 inline MarkedBlock::FreeList::FreeList() 223 : head(0) 224 , bytes(0) 225 { 235 236 static MarkedBlock::Handle* tryCreate(Heap&, MarkedAllocator*, size_t cellSize, const AllocatorAttributes&); 237 238 Handle& handle(); 239 240 VM* vm() const; 241 242 static bool isAtomAligned(const void*); 243 static MarkedBlock* blockFor(const void*); 244 static size_t firstAtom(); 245 size_t atomNumber(const void*); 246 247 size_t markCount(); 248 249 bool isMarked(const void*); 250 bool testAndSetMarked(const void*); 251 252 bool isMarkedOrNewlyAllocated(const HeapCell*); 253 254 bool isAtom(const void*); 255 void setMarked(const void*); 256 void clearMarked(const void*); 257 258 size_t cellSize(); 259 const AllocatorAttributes& attributes() const; 260 261 bool hasAnyMarked() const; 262 void noteMarked(); 263 264 WeakSet& weakSet(); 265 266 bool needsFlip(); 267 268 void flipIfNecessaryConcurrently(uint64_t heapVersion); 269 void flipIfNecessary(uint64_t heapVersion); 270 void flipIfNecessary(); 271 272 void assertFlipped(); 273 274 bool needsDestruction() const { return m_needsDestruction; } 275 276 private: 277 static const size_t atomAlignmentMask = atomSize - 1; 278 279 typedef char Atom[atomSize]; 280 281 MarkedBlock(VM&, Handle&); 282 Atom* atoms(); 283 284 void flipIfNecessaryConcurrentlySlow(); 285 void flipIfNecessarySlow(); 286 void clearMarks(); 287 void clearHasAnyMarked(); 288 289 void noteMarkedSlow(); 290 291 WTF::Bitmap<atomsPerBlock, WTF::BitmapAtomic, uint8_t> m_marks; 292 293 bool m_needsDestruction; 294 Lock m_lock; 295 296 // The actual mark count can be computed by doing: m_biasedMarkCount - m_markCountBias. Note 297 // that this count is racy. It will accurately detect whether or not exactly zero things were 298 // marked, but if N things got marked, then this may report anything in the range [1, N] (or 299 // before unbiased, it would be [1 + m_markCountBias, N + m_markCountBias].) 300 int16_t m_biasedMarkCount; 301 302 // We bias the mark count so that if m_biasedMarkCount >= 0 then the block should be retired. 303 // We go to all this trouble to make marking a bit faster: this way, marking knows when to 304 // retire a block using a js/jns on m_biasedMarkCount. 305 // 306 // For example, if a block has room for 100 objects and retirement happens whenever 90% are 307 // live, then m_markCountBias will be -90. This way, when marking begins, this will cause us to 308 // set m_biasedMarkCount to -90 as well, since: 309 // 310 // m_biasedMarkCount = actualMarkCount + m_markCountBias. 311 // 312 // Marking an object will increment m_biasedMarkCount. Once 90 objects get marked, we will have 313 // m_biasedMarkCount = 0, which will trigger retirement. In other words, we want to set 314 // m_markCountBias like so: 315 // 316 // m_markCountBias = -(minMarkedBlockUtilization * cellsPerBlock) 317 // 318 // All of this also means that you can detect if any objects are marked by doing: 319 // 320 // m_biasedMarkCount != m_markCountBias 321 int16_t m_markCountBias; 322 323 Handle& m_handle; 324 VM* m_vm; 325 326 uint64_t m_version; 327 }; 328 329 inline MarkedBlock::Handle& MarkedBlock::handle() 330 { 331 return m_handle; 332 } 333 334 inline MarkedBlock& MarkedBlock::Handle::block() 335 { 336 return *m_block; 337 } 338 339 inline size_t MarkedBlock::firstAtom() 340 { 341 return WTF::roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize; 342 } 343 344 inline MarkedBlock::Atom* MarkedBlock::atoms() 345 { 346 return reinterpret_cast<Atom*>(this); 347 } 348 349 inline bool MarkedBlock::isAtomAligned(const void* p) 350 { 351 return !(reinterpret_cast<Bits>(p) & atomAlignmentMask); 352 } 353 354 inline void* MarkedBlock::Handle::cellAlign(void* p) 355 { 356 Bits base = reinterpret_cast<Bits>(block().atoms() + firstAtom()); 357 Bits bits = reinterpret_cast<Bits>(p); 358 bits -= base; 359 bits -= bits % cellSize(); 360 bits += base; 361 return reinterpret_cast<void*>(bits); 362 } 363 364 inline MarkedBlock* MarkedBlock::blockFor(const void* p) 365 { 366 return reinterpret_cast<MarkedBlock*>(reinterpret_cast<Bits>(p) & blockMask); 367 } 368 369 inline MarkedAllocator* MarkedBlock::Handle::allocator() const 370 { 371 return m_allocator; 372 } 373 374 inline Heap* MarkedBlock::Handle::heap() const 375 { 376 return m_weakSet.heap(); 377 } 378 379 inline VM* MarkedBlock::Handle::vm() const 380 { 381 return m_weakSet.vm(); 382 } 383 384 inline VM* MarkedBlock::vm() const 385 { 386 return m_vm; 387 } 388 389 inline WeakSet& MarkedBlock::Handle::weakSet() 390 { 391 return m_weakSet; 392 } 393 394 inline WeakSet& MarkedBlock::weakSet() 395 { 396 return m_handle.weakSet(); 397 } 398 399 inline void MarkedBlock::Handle::shrink() 400 { 401 m_weakSet.shrink(); 402 } 403 404 inline unsigned MarkedBlock::Handle::visitWeakSet(HeapRootVisitor& heapRootVisitor) 405 { 406 return m_weakSet.visit(heapRootVisitor); 407 } 408 409 inline void MarkedBlock::Handle::reapWeakSet() 410 { 411 m_weakSet.reap(); 412 } 413 414 inline size_t MarkedBlock::Handle::cellSize() 415 { 416 return m_atomsPerCell * atomSize; 417 } 418 419 inline size_t MarkedBlock::cellSize() 420 { 421 return m_handle.cellSize(); 422 } 423 424 inline const AllocatorAttributes& MarkedBlock::Handle::attributes() const 425 { 426 return m_attributes; 427 } 428 429 inline const AllocatorAttributes& MarkedBlock::attributes() const 430 { 431 return m_handle.attributes(); 432 } 433 434 inline bool MarkedBlock::Handle::needsDestruction() const 435 { 436 return m_attributes.destruction == NeedsDestruction; 437 } 438 439 inline DestructionMode MarkedBlock::Handle::destruction() const 440 { 441 return m_attributes.destruction; 442 } 443 444 inline HeapCell::Kind MarkedBlock::Handle::cellKind() const 445 { 446 return m_attributes.cellKind; 447 } 448 449 inline size_t MarkedBlock::Handle::markCount() 450 { 451 return m_block->markCount(); 452 } 453 454 inline size_t MarkedBlock::Handle::size() 455 { 456 return markCount() * cellSize(); 457 } 458 459 inline size_t MarkedBlock::atomNumber(const void* p) 460 { 461 return (reinterpret_cast<Bits>(p) - reinterpret_cast<Bits>(this)) / atomSize; 462 } 463 464 inline void MarkedBlock::flipIfNecessary(uint64_t heapVersion) 465 { 466 if (UNLIKELY(heapVersion != m_version)) 467 flipIfNecessarySlow(); 468 } 469 470 inline void MarkedBlock::flipIfNecessaryConcurrently(uint64_t heapVersion) 471 { 472 if (UNLIKELY(heapVersion != m_version)) 473 flipIfNecessaryConcurrentlySlow(); 474 WTF::loadLoadFence(); 475 } 476 477 inline void MarkedBlock::Handle::flipIfNecessary(uint64_t heapVersion) 478 { 479 block().flipIfNecessary(heapVersion); 480 } 481 482 inline void MarkedBlock::Handle::flipIfNecessaryConcurrently(uint64_t heapVersion) 483 { 484 block().flipIfNecessaryConcurrently(heapVersion); 485 } 486 487 inline void MarkedBlock::Handle::flipForEdenCollection() 488 { 489 assertFlipped(); 490 491 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 492 493 ASSERT(m_state != New && m_state != FreeListed); 494 495 m_state = Marked; 496 } 497 498 #if ASSERT_DISABLED 499 inline void MarkedBlock::assertFlipped() 500 { 501 } 502 #endif // ASSERT_DISABLED 503 504 inline void MarkedBlock::Handle::assertFlipped() 505 { 506 block().assertFlipped(); 507 } 508 509 inline bool MarkedBlock::isMarked(const void* p) 510 { 511 assertFlipped(); 512 return m_marks.get(atomNumber(p)); 513 } 514 515 inline bool MarkedBlock::testAndSetMarked(const void* p) 516 { 517 assertFlipped(); 518 return m_marks.concurrentTestAndSet(atomNumber(p)); 519 } 520 521 inline bool MarkedBlock::Handle::isNewlyAllocated(const void* p) 522 { 523 return m_newlyAllocated->get(m_block->atomNumber(p)); 524 } 525 526 inline void MarkedBlock::Handle::setNewlyAllocated(const void* p) 527 { 528 m_newlyAllocated->set(m_block->atomNumber(p)); 529 } 530 531 inline void MarkedBlock::Handle::clearNewlyAllocated(const void* p) 532 { 533 m_newlyAllocated->clear(m_block->atomNumber(p)); 534 } 535 536 inline bool MarkedBlock::Handle::clearNewlyAllocated() 537 { 538 if (m_newlyAllocated) { 539 m_newlyAllocated = nullptr; 540 return true; 226 541 } 227 228 inline MarkedBlock::FreeList::FreeList(FreeCell* head, size_t bytes) 229 : head(head) 230 , bytes(bytes) 231 { 232 } 233 234 inline size_t MarkedBlock::firstAtom() 235 { 236 return WTF::roundUpToMultipleOf<atomSize>(sizeof(MarkedBlock)) / atomSize; 237 } 238 239 inline MarkedBlock::Atom* MarkedBlock::atoms() 240 { 241 return reinterpret_cast<Atom*>(this); 242 } 243 244 inline bool MarkedBlock::isAtomAligned(const void* p) 245 { 246 return !(reinterpret_cast<Bits>(p) & atomAlignmentMask); 247 } 248 249 inline MarkedBlock* MarkedBlock::blockFor(const void* p) 250 { 251 return reinterpret_cast<MarkedBlock*>(reinterpret_cast<Bits>(p) & blockMask); 252 } 253 254 inline MarkedAllocator* MarkedBlock::allocator() const 255 { 256 return m_allocator; 257 } 258 259 inline Heap* MarkedBlock::heap() const 260 { 261 return m_weakSet.heap(); 262 } 263 264 inline VM* MarkedBlock::vm() const 265 { 266 return m_weakSet.vm(); 267 } 268 269 inline WeakSet& MarkedBlock::weakSet() 270 { 271 return m_weakSet; 272 } 273 274 inline void MarkedBlock::shrink() 275 { 276 m_weakSet.shrink(); 277 } 278 279 inline void MarkedBlock::visitWeakSet(HeapRootVisitor& heapRootVisitor) 280 { 281 m_weakSet.visit(heapRootVisitor); 282 } 283 284 inline void MarkedBlock::reapWeakSet() 285 { 286 m_weakSet.reap(); 287 } 288 289 inline void MarkedBlock::willRemoveBlock() 290 { 291 ASSERT(m_state != Retired); 292 } 293 294 inline void MarkedBlock::didConsumeFreeList() 295 { 296 HEAP_LOG_BLOCK_STATE_TRANSITION(this); 297 298 ASSERT(m_state == FreeListed); 299 m_state = Allocated; 300 } 301 302 inline size_t MarkedBlock::markCount() 303 { 304 return m_marks.count(); 305 } 306 307 inline bool MarkedBlock::isEmpty() 308 { 309 return m_marks.isEmpty() && m_weakSet.isEmpty() && (!m_newlyAllocated || m_newlyAllocated->isEmpty()); 310 } 311 312 inline size_t MarkedBlock::cellSize() 313 { 314 return m_atomsPerCell * atomSize; 315 } 316 317 inline const AllocatorAttributes& MarkedBlock::attributes() const 318 { 319 return m_attributes; 320 } 321 322 inline bool MarkedBlock::needsDestruction() const 323 { 324 return m_attributes.destruction == NeedsDestruction; 325 } 326 327 inline DestructionMode MarkedBlock::destruction() const 328 { 329 return m_attributes.destruction; 330 } 331 332 inline HeapCell::Kind MarkedBlock::cellKind() const 333 { 334 return m_attributes.cellKind; 335 } 336 337 inline size_t MarkedBlock::size() 338 { 339 return markCount() * cellSize(); 340 } 341 342 inline size_t MarkedBlock::capacity() 343 { 344 return m_capacity; 345 } 346 347 inline size_t MarkedBlock::atomNumber(const void* p) 348 { 349 return (reinterpret_cast<Bits>(p) - reinterpret_cast<Bits>(this)) / atomSize; 350 } 351 352 inline bool MarkedBlock::isMarked(const void* p) 353 { 354 return m_marks.get(atomNumber(p)); 355 } 356 357 inline bool MarkedBlock::testAndSetMarked(const void* p) 358 { 359 return m_marks.concurrentTestAndSet(atomNumber(p)); 360 } 361 362 inline void MarkedBlock::setMarked(const void* p) 363 { 364 m_marks.set(atomNumber(p)); 365 } 366 367 inline void MarkedBlock::clearMarked(const void* p) 368 { 369 ASSERT(m_marks.get(atomNumber(p))); 370 m_marks.clear(atomNumber(p)); 371 } 372 373 inline bool MarkedBlock::isNewlyAllocated(const void* p) 374 { 375 return m_newlyAllocated->get(atomNumber(p)); 376 } 377 378 inline void MarkedBlock::setNewlyAllocated(const void* p) 379 { 380 m_newlyAllocated->set(atomNumber(p)); 381 } 382 383 inline void MarkedBlock::clearNewlyAllocated(const void* p) 384 { 385 m_newlyAllocated->clear(atomNumber(p)); 386 } 387 388 inline bool MarkedBlock::clearNewlyAllocated() 389 { 390 if (m_newlyAllocated) { 391 m_newlyAllocated = nullptr; 392 return true; 393 } 394 return false; 395 } 396 397 inline bool MarkedBlock::isMarkedOrNewlyAllocated(const HeapCell* cell) 398 { 399 ASSERT(m_state == Retired || m_state == Marked); 400 return m_marks.get(atomNumber(cell)) || (m_newlyAllocated && isNewlyAllocated(cell)); 401 } 402 403 inline bool MarkedBlock::isLive(const HeapCell* cell) 404 { 405 switch (m_state) { 406 case Allocated: 407 return true; 408 409 case Retired: 410 case Marked: 411 return isMarkedOrNewlyAllocated(cell); 412 413 case New: 414 case FreeListed: 415 RELEASE_ASSERT_NOT_REACHED(); 416 return false; 417 } 418 542 return false; 543 } 544 545 inline bool MarkedBlock::Handle::isMarkedOrNewlyAllocated(const HeapCell* cell) 546 { 547 ASSERT(m_state == Marked); 548 return m_block->isMarked(cell) || (m_newlyAllocated && isNewlyAllocated(cell)); 549 } 550 551 inline bool MarkedBlock::isMarkedOrNewlyAllocated(const HeapCell* cell) 552 { 553 ASSERT(m_handle.m_state == Marked); 554 return isMarked(cell) || (m_handle.m_newlyAllocated && m_handle.isNewlyAllocated(cell)); 555 } 556 557 inline bool MarkedBlock::Handle::isLive(const HeapCell* cell) 558 { 559 assertFlipped(); 560 switch (m_state) { 561 case Allocated: 562 return true; 563 564 case Marked: 565 return isMarkedOrNewlyAllocated(cell); 566 567 case New: 568 case FreeListed: 419 569 RELEASE_ASSERT_NOT_REACHED(); 420 570 return false; 421 571 } 422 572 423 inline bool MarkedBlock::isAtom(const void* p) 573 RELEASE_ASSERT_NOT_REACHED(); 574 return false; 575 } 576 577 inline bool MarkedBlock::isAtom(const void* p) 578 { 579 ASSERT(MarkedBlock::isAtomAligned(p)); 580 size_t atomNumber = this->atomNumber(p); 581 size_t firstAtom = MarkedBlock::firstAtom(); 582 if (atomNumber < firstAtom) // Filters pointers into MarkedBlock metadata. 583 return false; 584 if ((atomNumber - firstAtom) % m_handle.m_atomsPerCell) // Filters pointers into cell middles. 585 return false; 586 if (atomNumber >= m_handle.m_endAtom) // Filters pointers into invalid cells out of the range. 587 return false; 588 return true; 589 } 590 591 inline bool MarkedBlock::Handle::isLiveCell(const void* p) 592 { 593 if (!m_block->isAtom(p)) 594 return false; 595 return isLive(static_cast<const HeapCell*>(p)); 596 } 597 598 template <typename Functor> 599 inline IterationStatus MarkedBlock::Handle::forEachCell(const Functor& functor) 600 { 601 HeapCell::Kind kind = m_attributes.cellKind; 602 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 603 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&m_block->atoms()[i]); 604 if (functor(cell, kind) == IterationStatus::Done) 605 return IterationStatus::Done; 606 } 607 return IterationStatus::Continue; 608 } 609 610 template <typename Functor> 611 inline IterationStatus MarkedBlock::Handle::forEachLiveCell(const Functor& functor) 612 { 613 flipIfNecessary(); 614 HeapCell::Kind kind = m_attributes.cellKind; 615 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 616 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&m_block->atoms()[i]); 617 if (!isLive(cell)) 618 continue; 619 620 if (functor(cell, kind) == IterationStatus::Done) 621 return IterationStatus::Done; 622 } 623 return IterationStatus::Continue; 624 } 625 626 template <typename Functor> 627 inline IterationStatus MarkedBlock::Handle::forEachDeadCell(const Functor& functor) 628 { 629 flipIfNecessary(); 630 HeapCell::Kind kind = m_attributes.cellKind; 631 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 632 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&m_block->atoms()[i]); 633 if (isLive(cell)) 634 continue; 635 636 if (functor(cell, kind) == IterationStatus::Done) 637 return IterationStatus::Done; 638 } 639 return IterationStatus::Continue; 640 } 641 642 inline bool MarkedBlock::Handle::needsSweeping() const 643 { 644 const_cast<MarkedBlock::Handle*>(this)->flipIfNecessary(); 645 return m_state == Marked; 646 } 647 648 inline bool MarkedBlock::Handle::isAllocated() const 649 { 650 const_cast<MarkedBlock::Handle*>(this)->flipIfNecessary(); 651 return m_state == Allocated; 652 } 653 654 inline bool MarkedBlock::Handle::isMarked() const 655 { 656 const_cast<MarkedBlock::Handle*>(this)->flipIfNecessary(); 657 return m_state == Marked; 658 } 659 660 inline bool MarkedBlock::Handle::isFreeListed() const 661 { 662 const_cast<MarkedBlock::Handle*>(this)->flipIfNecessary(); 663 return m_state == FreeListed; 664 } 665 666 inline bool MarkedBlock::hasAnyMarked() const 667 { 668 return m_biasedMarkCount != m_markCountBias; 669 } 670 671 inline void MarkedBlock::noteMarked() 672 { 673 // This is racy by design. We don't want to pay the price of an atomic increment! 674 int16_t biasedMarkCount = m_biasedMarkCount; 675 ++biasedMarkCount; 676 m_biasedMarkCount = biasedMarkCount; 677 if (UNLIKELY(!biasedMarkCount)) 678 noteMarkedSlow(); 679 } 680 681 } // namespace JSC 682 683 namespace WTF { 684 685 struct MarkedBlockHash : PtrHash<JSC::MarkedBlock*> { 686 static unsigned hash(JSC::MarkedBlock* const& key) 424 687 { 425 ASSERT(MarkedBlock::isAtomAligned(p)); 426 size_t atomNumber = this->atomNumber(p); 427 size_t firstAtom = this->firstAtom(); 428 if (atomNumber < firstAtom) // Filters pointers into MarkedBlock metadata. 429 return false; 430 if ((atomNumber - firstAtom) % m_atomsPerCell) // Filters pointers into cell middles. 431 return false; 432 if (atomNumber >= m_endAtom) // Filters pointers into invalid cells out of the range. 433 return false; 434 return true; 688 // Aligned VM regions tend to be monotonically increasing integers, 689 // which is a great hash function, but we have to remove the low bits, 690 // since they're always zero, which is a terrible hash function! 691 return reinterpret_cast<JSC::Bits>(key) / JSC::MarkedBlock::blockSize; 435 692 } 436 437 inline bool MarkedBlock::isLiveCell(const void* p) 438 { 439 if (!isAtom(p)) 440 return false; 441 return isLive(static_cast<const HeapCell*>(p)); 442 } 443 444 template <typename Functor> inline IterationStatus MarkedBlock::forEachCell(const Functor& functor) 445 { 446 HeapCell::Kind kind = m_attributes.cellKind; 447 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 448 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&atoms()[i]); 449 if (functor(cell, kind) == IterationStatus::Done) 450 return IterationStatus::Done; 451 } 452 return IterationStatus::Continue; 453 } 454 455 template <typename Functor> inline IterationStatus MarkedBlock::forEachLiveCell(const Functor& functor) 456 { 457 HeapCell::Kind kind = m_attributes.cellKind; 458 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 459 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&atoms()[i]); 460 if (!isLive(cell)) 461 continue; 462 463 if (functor(cell, kind) == IterationStatus::Done) 464 return IterationStatus::Done; 465 } 466 return IterationStatus::Continue; 467 } 468 469 template <typename Functor> inline IterationStatus MarkedBlock::forEachDeadCell(const Functor& functor) 470 { 471 HeapCell::Kind kind = m_attributes.cellKind; 472 for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) { 473 HeapCell* cell = reinterpret_cast_ptr<HeapCell*>(&atoms()[i]); 474 if (isLive(cell)) 475 continue; 476 477 if (functor(cell, kind) == IterationStatus::Done) 478 return IterationStatus::Done; 479 } 480 return IterationStatus::Continue; 481 } 482 483 inline bool MarkedBlock::needsSweeping() const 484 { 485 return m_state == Marked; 486 } 487 488 inline bool MarkedBlock::isAllocated() const 489 { 490 return m_state == Allocated; 491 } 492 493 inline bool MarkedBlock::isMarkedOrRetired() const 494 { 495 return m_state == Marked || m_state == Retired; 496 } 497 498 } // namespace JSC 499 500 namespace WTF { 501 502 struct MarkedBlockHash : PtrHash<JSC::MarkedBlock*> { 503 static unsigned hash(JSC::MarkedBlock* const& key) 504 { 505 // Aligned VM regions tend to be monotonically increasing integers, 506 // which is a great hash function, but we have to remove the low bits, 507 // since they're always zero, which is a terrible hash function! 508 return reinterpret_cast<JSC::Bits>(key) / JSC::MarkedBlock::blockSize; 509 } 510 }; 511 512 template<> struct DefaultHash<JSC::MarkedBlock*> { 513 typedef MarkedBlockHash Hash; 514 }; 693 }; 694 695 template<> struct DefaultHash<JSC::MarkedBlock*> { 696 typedef MarkedBlockHash Hash; 697 }; 698 699 void printInternal(PrintStream& out, JSC::MarkedBlock::BlockState); 515 700 516 701 } // namespace WTF -
trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp
r204912 r205462 25 25 #include "JSObject.h" 26 26 #include "JSCInlines.h" 27 #include "SuperSampler.h" 28 #include <wtf/ListDump.h> 27 29 28 30 namespace JSC { 31 32 std::array<size_t, MarkedSpace::numSizeClasses> MarkedSpace::s_sizeClassForSizeStep; 33 34 namespace { 35 36 const Vector<size_t>& sizeClasses() 37 { 38 static Vector<size_t>* result; 39 static std::once_flag once; 40 std::call_once( 41 once, 42 [] { 43 result = new Vector<size_t>(); 44 45 auto add = [&] (size_t sizeClass) { 46 if (Options::dumpSizeClasses()) 47 dataLog("Adding JSC MarkedSpace size class: ", sizeClass, "\n"); 48 // Perform some validation as we go. 49 RELEASE_ASSERT(!(sizeClass % MarkedSpace::sizeStep)); 50 if (result->isEmpty()) 51 RELEASE_ASSERT(sizeClass == MarkedSpace::sizeStep); 52 else 53 RELEASE_ASSERT(sizeClass > result->last()); 54 result->append(sizeClass); 55 }; 56 57 // This is a definition of the size classes in our GC. It must define all of the 58 // size classes from sizeStep up to largeCutoff. 59 60 // Have very precise size classes for the small stuff. This is a loop to make it easy to reduce 61 // atomSize. 62 for (size_t size = MarkedSpace::sizeStep; size < MarkedSpace::preciseCutoff; size += MarkedSpace::sizeStep) 63 add(size); 64 65 // We want to make sure that the remaining size classes minimize internal fragmentation (i.e. 66 // the wasted space at the tail end of a MarkedBlock) while proceeding roughly in an exponential 67 // way starting at just above the precise size classes to four cells per block. 68 69 if (Options::dumpSizeClasses()) 70 dataLog(" Marked block payload size: ", static_cast<size_t>(MarkedSpace::blockPayload), "\n"); 71 72 for (unsigned i = 0; ; ++i) { 73 double approximateSize = MarkedSpace::preciseCutoff * pow(Options::sizeClassProgression(), i); 74 75 if (Options::dumpSizeClasses()) 76 dataLog(" Next size class as a double: ", approximateSize, "\n"); 77 78 size_t approximateSizeInBytes = static_cast<size_t>(approximateSize); 79 80 if (Options::dumpSizeClasses()) 81 dataLog(" Next size class as bytes: ", approximateSizeInBytes, "\n"); 82 83 // Make sure that the computer did the math correctly. 84 RELEASE_ASSERT(approximateSizeInBytes >= MarkedSpace::preciseCutoff); 85 86 if (approximateSizeInBytes > MarkedSpace::largeCutoff) 87 break; 88 89 size_t sizeClass = 90 WTF::roundUpToMultipleOf<MarkedSpace::sizeStep>(approximateSizeInBytes); 91 92 if (Options::dumpSizeClasses()) 93 dataLog(" Size class: ", sizeClass, "\n"); 94 95 // Optimize the size class so that there isn't any slop at the end of the block's 96 // payload. 97 unsigned cellsPerBlock = MarkedSpace::blockPayload / sizeClass; 98 size_t possiblyBetterSizeClass = (MarkedSpace::blockPayload / cellsPerBlock) & ~(MarkedSpace::sizeStep - 1); 99 100 if (Options::dumpSizeClasses()) 101 dataLog(" Possibly better size class: ", possiblyBetterSizeClass, "\n"); 102 103 // The size class we just came up with is better than the other one if it reduces 104 // total wastage assuming we only allocate cells of that size. 105 size_t originalWastage = MarkedSpace::blockPayload - cellsPerBlock * sizeClass; 106 size_t newWastage = (possiblyBetterSizeClass - sizeClass) * cellsPerBlock; 107 108 if (Options::dumpSizeClasses()) 109 dataLog(" Original wastage: ", originalWastage, ", new wastage: ", newWastage, "\n"); 110 111 size_t betterSizeClass; 112 if (newWastage > originalWastage) 113 betterSizeClass = sizeClass; 114 else 115 betterSizeClass = possiblyBetterSizeClass; 116 117 if (Options::dumpSizeClasses()) 118 dataLog(" Choosing size class: ", betterSizeClass, "\n"); 119 120 if (betterSizeClass == result->last()) { 121 // Defense for when expStep is small. 122 continue; 123 } 124 125 // This is usually how we get out of the loop. 126 if (betterSizeClass > MarkedSpace::largeCutoff 127 || betterSizeClass > Options::largeAllocationCutoff()) 128 break; 129 130 add(betterSizeClass); 131 } 132 133 if (Options::dumpSizeClasses()) 134 dataLog("JSC Heap MarkedSpace size class dump: ", listDump(*result), "\n"); 135 136 // We have an optimiation in MarkedSpace::optimalSizeFor() that assumes things about 137 // the size class table. This checks our results against that function's assumptions. 138 for (size_t size = MarkedSpace::sizeStep, i = 0; size <= MarkedSpace::preciseCutoff; size += MarkedSpace::sizeStep, i++) 139 RELEASE_ASSERT(result->at(i) == size); 140 }); 141 return *result; 142 } 143 144 template<typename TableType, typename SizeClassCons, typename DefaultCons> 145 void buildSizeClassTable(TableType& table, const SizeClassCons& cons, const DefaultCons& defaultCons) 146 { 147 size_t nextIndex = 0; 148 for (size_t sizeClass : sizeClasses()) { 149 auto entry = cons(sizeClass); 150 size_t index = MarkedSpace::sizeClassToIndex(sizeClass); 151 for (size_t i = nextIndex; i <= index; ++i) 152 table[i] = entry; 153 nextIndex = index + 1; 154 } 155 for (size_t i = nextIndex; i < MarkedSpace::numSizeClasses; ++i) 156 table[i] = defaultCons(MarkedSpace::indexToSizeClass(i)); 157 } 158 159 } // anonymous namespace 160 161 void MarkedSpace::initializeSizeClassForStepSize() 162 { 163 // We call this multiple times and we may call it simultaneously from multiple threads. That's 164 // OK, since it always stores the same values into the table. 165 166 buildSizeClassTable( 167 s_sizeClassForSizeStep, 168 [&] (size_t sizeClass) -> size_t { 169 return sizeClass; 170 }, 171 [&] (size_t sizeClass) -> size_t { 172 return sizeClass; 173 }); 174 } 29 175 30 176 MarkedSpace::MarkedSpace(Heap* heap) … … 33 179 , m_isIterating(false) 34 180 { 35 forEachAllocator( 36 [&] (MarkedAllocator& allocator, size_t cellSize, AllocatorAttributes attributes) -> IterationStatus { 37 allocator.init(heap, this, cellSize, attributes); 181 initializeSizeClassForStepSize(); 182 183 forEachSubspace( 184 [&] (Subspace& subspace, AllocatorAttributes attributes) -> IterationStatus { 185 subspace.attributes = attributes; 186 187 buildSizeClassTable( 188 subspace.allocatorForSizeStep, 189 [&] (size_t sizeClass) -> MarkedAllocator* { 190 return subspace.bagOfAllocators.add(heap, this, sizeClass, attributes); 191 }, 192 [&] (size_t) -> MarkedAllocator* { 193 return nullptr; 194 }); 195 38 196 return IterationStatus::Continue; 39 197 }); … … 43 201 { 44 202 forEachBlock( 45 [&] (MarkedBlock * block) {203 [&] (MarkedBlock::Handle* block) { 46 204 freeBlock(block); 47 205 }); … … 53 211 stopAllocating(); 54 212 forEachAllocator( 55 [&] (MarkedAllocator& allocator , size_t, AllocatorAttributes) -> IterationStatus {213 [&] (MarkedAllocator& allocator) -> IterationStatus { 56 214 allocator.lastChanceToFinalize(); 57 215 return IterationStatus::Continue; 58 216 }); 217 for (LargeAllocation* allocation : m_largeAllocations) 218 allocation->lastChanceToFinalize(); 219 } 220 221 void* MarkedSpace::allocate(Subspace& subspace, size_t bytes) 222 { 223 if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) 224 return allocator->allocate(); 225 return allocateLarge(subspace, bytes); 226 } 227 228 void* MarkedSpace::tryAllocate(Subspace& subspace, size_t bytes) 229 { 230 if (MarkedAllocator* allocator = allocatorFor(subspace, bytes)) 231 return allocator->tryAllocate(); 232 return tryAllocateLarge(subspace, bytes); 233 } 234 235 void* MarkedSpace::allocateLarge(Subspace& subspace, size_t size) 236 { 237 void* result = tryAllocateLarge(subspace, size); 238 RELEASE_ASSERT(result); 239 return result; 240 } 241 242 void* MarkedSpace::tryAllocateLarge(Subspace& subspace, size_t size) 243 { 244 m_heap->collectIfNecessaryOrDefer(); 245 246 size = WTF::roundUpToMultipleOf<sizeStep>(size); 247 LargeAllocation* allocation = LargeAllocation::tryCreate(*m_heap, size, subspace.attributes); 248 if (!allocation) 249 return nullptr; 250 251 m_largeAllocations.append(allocation); 252 m_heap->didAllocate(size); 253 m_capacity += size; 254 return allocation->cell(); 59 255 } 60 256 … … 63 259 m_heap->sweeper()->willFinishSweeping(); 64 260 forEachBlock( 65 [&] (MarkedBlock * block) {261 [&] (MarkedBlock::Handle* block) { 66 262 block->sweep(); 67 263 }); 264 } 265 266 void MarkedSpace::sweepLargeAllocations() 267 { 268 RELEASE_ASSERT(m_largeAllocationsNurseryOffset == m_largeAllocations.size()); 269 unsigned srcIndex = m_largeAllocationsNurseryOffsetForSweep; 270 unsigned dstIndex = srcIndex; 271 while (srcIndex < m_largeAllocations.size()) { 272 LargeAllocation* allocation = m_largeAllocations[srcIndex++]; 273 allocation->sweep(); 274 if (allocation->isEmpty()) { 275 m_capacity -= allocation->cellSize(); 276 allocation->destroy(); 277 continue; 278 } 279 m_largeAllocations[dstIndex++] = allocation; 280 } 281 m_largeAllocations.resize(dstIndex); 282 m_largeAllocationsNurseryOffset = m_largeAllocations.size(); 68 283 } 69 284 … … 74 289 m_heap->sweeper()->willFinishSweeping(); 75 290 forEachBlock( 76 [&] (MarkedBlock * block) {291 [&] (MarkedBlock::Handle* block) { 77 292 if (block->needsSweeping()) 78 293 block->sweep(); … … 83 298 { 84 299 forEachAllocator( 85 [&] (MarkedAllocator& allocator , size_t, AllocatorAttributes) -> IterationStatus {300 [&] (MarkedAllocator& allocator) -> IterationStatus { 86 301 allocator.reset(); 87 302 return IterationStatus::Continue; … … 89 304 90 305 m_blocksWithNewObjects.clear(); 306 m_activeWeakSets.takeFrom(m_newActiveWeakSets); 307 if (m_heap->operationInProgress() == EdenCollection) 308 m_largeAllocationsNurseryOffsetForSweep = m_largeAllocationsNurseryOffset; 309 else 310 m_largeAllocationsNurseryOffsetForSweep = 0; 311 m_largeAllocationsNurseryOffset = m_largeAllocations.size(); 91 312 } 92 313 93 314 void MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor) 94 315 { 95 if (m_heap->operationInProgress() == EdenCollection) { 96 for (unsigned i = 0; i < m_blocksWithNewObjects.size(); ++i) 97 m_blocksWithNewObjects[i]->visitWeakSet(heapRootVisitor); 98 } else { 99 forEachBlock( 100 [&] (MarkedBlock* block) { 101 block->visitWeakSet(heapRootVisitor); 102 }); 103 } 316 auto visit = [&] (WeakSet* weakSet) { 317 weakSet->visit(heapRootVisitor); 318 }; 319 320 m_newActiveWeakSets.forEach(visit); 321 322 if (m_heap->operationInProgress() == FullCollection) 323 m_activeWeakSets.forEach(visit); 104 324 } 105 325 106 326 void MarkedSpace::reapWeakSets() 107 327 { 108 if (m_heap->operationInProgress() == EdenCollection) { 109 for (unsigned i = 0; i < m_blocksWithNewObjects.size(); ++i) 110 m_blocksWithNewObjects[i]->reapWeakSet(); 111 } else { 112 forEachBlock( 113 [&] (MarkedBlock* block) { 114 block->reapWeakSet(); 115 }); 116 } 117 } 118 119 template <typename Functor> 120 void MarkedSpace::forEachAllocator(const Functor& functor) 121 { 122 forEachSubspace( 123 [&] (Subspace& subspace, AllocatorAttributes attributes) -> IterationStatus { 124 for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { 125 if (functor(allocatorFor(subspace, cellSize), cellSize, attributes) == IterationStatus::Done) 126 return IterationStatus::Done; 127 } 128 for (size_t cellSize = impreciseStart; cellSize <= impreciseCutoff; cellSize += impreciseStep) { 129 if (functor(allocatorFor(subspace, cellSize), cellSize, attributes) == IterationStatus::Done) 130 return IterationStatus::Done; 131 } 132 if (functor(subspace.largeAllocator, 0, attributes) == IterationStatus::Done) 133 return IterationStatus::Done; 134 135 return IterationStatus::Continue; 136 }); 328 auto visit = [&] (WeakSet* weakSet) { 329 weakSet->reap(); 330 }; 331 332 m_newActiveWeakSets.forEach(visit); 333 334 if (m_heap->operationInProgress() == FullCollection) 335 m_activeWeakSets.forEach(visit); 137 336 } 138 337 … … 141 340 ASSERT(!isIterating()); 142 341 forEachAllocator( 143 [&] (MarkedAllocator& allocator , size_t, AllocatorAttributes) -> IterationStatus {342 [&] (MarkedAllocator& allocator) -> IterationStatus { 144 343 allocator.stopAllocating(); 145 344 return IterationStatus::Continue; 345 }); 346 } 347 348 void MarkedSpace::prepareForMarking() 349 { 350 if (m_heap->operationInProgress() == EdenCollection) 351 m_largeAllocationsOffsetForThisCollection = m_largeAllocationsNurseryOffset; 352 else 353 m_largeAllocationsOffsetForThisCollection = 0; 354 m_largeAllocationsForThisCollectionBegin = m_largeAllocations.begin() + m_largeAllocationsOffsetForThisCollection; 355 m_largeAllocationsForThisCollectionSize = m_largeAllocations.size() - m_largeAllocationsOffsetForThisCollection; 356 m_largeAllocationsForThisCollectionEnd = m_largeAllocations.end(); 357 RELEASE_ASSERT(m_largeAllocationsForThisCollectionEnd == m_largeAllocationsForThisCollectionBegin + m_largeAllocationsForThisCollectionSize); 358 std::sort( 359 m_largeAllocationsForThisCollectionBegin, m_largeAllocationsForThisCollectionEnd, 360 [&] (LargeAllocation* a, LargeAllocation* b) { 361 return a < b; 146 362 }); 147 363 } … … 151 367 ASSERT(isIterating()); 152 368 forEachAllocator( 153 [&] (MarkedAllocator& allocator , size_t, AllocatorAttributes) -> IterationStatus {369 [&] (MarkedAllocator& allocator) -> IterationStatus { 154 370 allocator.resumeAllocating(); 155 371 return IterationStatus::Continue; 156 372 }); 373 // Nothing to do for LargeAllocations. 157 374 } 158 375 … … 161 378 bool result = false; 162 379 forEachAllocator( 163 [&] (MarkedAllocator& allocator , size_t, AllocatorAttributes) -> IterationStatus {380 [&] (MarkedAllocator& allocator) -> IterationStatus { 164 381 if (allocator.isPagedOut(deadline)) { 165 382 result = true; … … 168 385 return IterationStatus::Continue; 169 386 }); 387 // FIXME: Consider taking LargeAllocations into account here. 170 388 return result; 171 389 } 172 390 173 void MarkedSpace::freeBlock(MarkedBlock * block)391 void MarkedSpace::freeBlock(MarkedBlock::Handle* block) 174 392 { 175 393 block->allocator()->removeBlock(block); 176 m_capacity -= block->capacity();177 m_blocks.remove( block);178 MarkedBlock::destroy(*m_heap, block);179 } 180 181 void MarkedSpace::freeOrShrinkBlock(MarkedBlock * block)394 m_capacity -= MarkedBlock::blockSize; 395 m_blocks.remove(&block->block()); 396 delete block; 397 } 398 399 void MarkedSpace::freeOrShrinkBlock(MarkedBlock::Handle* block) 182 400 { 183 401 if (!block->isEmpty()) { … … 192 410 { 193 411 forEachBlock( 194 [&] (MarkedBlock * block) {412 [&] (MarkedBlock::Handle* block) { 195 413 freeOrShrinkBlock(block); 196 414 }); 415 // For LargeAllocations, we do the moral equivalent in sweepLargeAllocations(). 197 416 } 198 417 … … 200 419 { 201 420 forEachAllocator( 202 [&] (MarkedAllocator& allocator, size_t size, AllocatorAttributes) -> IterationStatus { 203 if (!size) { 204 // This means it's a largeAllocator. 205 allocator.forEachBlock( 206 [&] (MarkedBlock* block) { 207 block->clearNewlyAllocated(); 208 }); 209 return IterationStatus::Continue; 210 } 211 212 if (MarkedBlock* block = allocator.takeLastActiveBlock()) 421 [&] (MarkedAllocator& allocator) -> IterationStatus { 422 if (MarkedBlock::Handle* block = allocator.takeLastActiveBlock()) 213 423 block->clearNewlyAllocated(); 214 424 return IterationStatus::Continue; 215 425 }); 426 427 for (unsigned i = m_largeAllocationsOffsetForThisCollection; i < m_largeAllocations.size(); ++i) 428 m_largeAllocations[i]->clearNewlyAllocated(); 216 429 217 430 #if !ASSERT_DISABLED 218 431 forEachBlock( 219 [&] (MarkedBlock * block) {432 [&] (MarkedBlock::Handle* block) { 220 433 ASSERT(!block->clearNewlyAllocated()); 221 434 }); 435 436 for (LargeAllocation* allocation : m_largeAllocations) 437 ASSERT(!allocation->isNewlyAllocated()); 222 438 #endif // !ASSERT_DISABLED 223 439 } 224 440 225 441 #ifndef NDEBUG 226 struct VerifyMarked OrRetired: MarkedBlock::VoidFunctor {227 void operator()(MarkedBlock * block) const442 struct VerifyMarked : MarkedBlock::VoidFunctor { 443 void operator()(MarkedBlock::Handle* block) const 228 444 { 445 if (block->needsFlip()) 446 return; 229 447 switch (block->m_state) { 230 448 case MarkedBlock::Marked: 231 case MarkedBlock::Retired:232 449 return; 233 450 default: … … 238 455 #endif 239 456 240 void MarkedSpace:: clearMarks()457 void MarkedSpace::flip() 241 458 { 242 459 if (m_heap->operationInProgress() == EdenCollection) { 243 460 for (unsigned i = 0; i < m_blocksWithNewObjects.size(); ++i) 244 m_blocksWithNewObjects[i]-> clearMarks();461 m_blocksWithNewObjects[i]->flipForEdenCollection(); 245 462 } else { 246 forEachBlock( 247 [&] (MarkedBlock* block) { 248 block->clearMarks(); 249 }); 463 m_version++; // Henceforth, flipIfNecessary() will trigger on all blocks. 464 for (LargeAllocation* allocation : m_largeAllocations) 465 allocation->flip(); 250 466 } 251 467 252 468 #ifndef NDEBUG 253 VerifyMarked OrRetiredverifyFunctor;469 VerifyMarked verifyFunctor; 254 470 forEachBlock(verifyFunctor); 255 471 #endif … … 270 486 } 271 487 488 size_t MarkedSpace::objectCount() 489 { 490 size_t result = 0; 491 forEachBlock( 492 [&] (MarkedBlock::Handle* block) { 493 result += block->markCount(); 494 }); 495 for (LargeAllocation* allocation : m_largeAllocations) { 496 if (allocation->isMarked()) 497 result++; 498 } 499 return result; 500 } 501 502 size_t MarkedSpace::size() 503 { 504 size_t result = 0; 505 forEachBlock( 506 [&] (MarkedBlock::Handle* block) { 507 result += block->markCount() * block->cellSize(); 508 }); 509 for (LargeAllocation* allocation : m_largeAllocations) { 510 if (allocation->isMarked()) 511 result += allocation->cellSize(); 512 } 513 return result; 514 } 515 516 size_t MarkedSpace::capacity() 517 { 518 return m_capacity; 519 } 520 521 void MarkedSpace::addActiveWeakSet(WeakSet* weakSet) 522 { 523 // We conservatively assume that the WeakSet should belong in the new set. In fact, some weak 524 // sets might contain new weak handles even though they are tied to old objects. This slightly 525 // increases the amount of scanning that an eden collection would have to do, but the effect 526 // ought to be small. 527 m_newActiveWeakSets.append(weakSet); 528 } 529 530 void MarkedSpace::didAddBlock(MarkedBlock::Handle* block) 531 { 532 m_capacity += MarkedBlock::blockSize; 533 m_blocks.add(&block->block()); 534 } 535 536 void MarkedSpace::didAllocateInBlock(MarkedBlock::Handle* block) 537 { 538 block->assertFlipped(); 539 m_blocksWithNewObjects.append(block); 540 541 if (block->weakSet().isOnList()) { 542 block->weakSet().remove(); 543 m_newActiveWeakSets.append(&block->weakSet()); 544 } 545 } 546 272 547 } // namespace JSC -
trunk/Source/JavaScriptCore/heap/MarkedSpace.h
r204912 r205462 24 24 25 25 #include "IterationStatus.h" 26 #include "LargeAllocation.h" 26 27 #include "MarkedAllocator.h" 27 28 #include "MarkedBlock.h" 28 29 #include "MarkedBlockSet.h" 29 30 #include <array> 31 #include <wtf/Bag.h> 30 32 #include <wtf/HashSet.h> 31 33 #include <wtf/Noncopyable.h> 32 34 #include <wtf/RetainPtr.h> 35 #include <wtf/SentinelLinkedList.h> 33 36 #include <wtf/Vector.h> 34 37 … … 38 41 class HeapIterationScope; 39 42 class LLIntOffsetsExtractor; 43 class WeakSet; 40 44 41 45 class MarkedSpace { 42 46 WTF_MAKE_NONCOPYABLE(MarkedSpace); 43 47 public: 44 // [ 16 ... 768 ] 45 static const size_t preciseStep = MarkedBlock::atomSize; 46 static const size_t preciseCutoff = 768; 47 static const size_t preciseCount = preciseCutoff / preciseStep; 48 49 // [ 1024 ... blockSize/2 ] 50 static const size_t impreciseStart = 1024; 51 static const size_t impreciseStep = 256; 52 static const size_t impreciseCutoff = MarkedBlock::blockSize / 2; 53 static const size_t impreciseCount = impreciseCutoff / impreciseStep; 54 48 // sizeStep is really a synonym for atomSize; it's no accident that they are the same. 49 static const size_t sizeStep = MarkedBlock::atomSize; 50 51 // Sizes up to this amount get a size class for each size step. 52 static const size_t preciseCutoff = 80; 53 54 // The amount of available payload in a block is the block's size minus the header. But the 55 // header size might not be atom size aligned, so we round down the result accordingly. 56 static const size_t blockPayload = (MarkedBlock::blockSize - sizeof(MarkedBlock)) & ~(MarkedBlock::atomSize - 1); 57 58 // The largest cell we're willing to allocate in a MarkedBlock the "normal way" (i.e. using size 59 // classes, rather than a large allocation) is half the size of the payload, rounded down. This 60 // ensures that we only use the size class approach if it means being able to pack two things 61 // into one block. 62 static const size_t largeCutoff = (blockPayload / 2) & ~(sizeStep - 1); 63 64 static const size_t numSizeClasses = largeCutoff / sizeStep; 65 66 static size_t sizeClassToIndex(size_t size) 67 { 68 ASSERT(size); 69 return (size + sizeStep - 1) / sizeStep - 1; 70 } 71 72 static size_t indexToSizeClass(size_t index) 73 { 74 return (index + 1) * sizeStep; 75 } 76 77 // Each Subspace corresponds to all of the blocks for all of the sizes for some "class" of 78 // objects. There are three classes: non-destructor JSCells, destructor JSCells, and auxiliary. 79 // MarkedSpace is set up to make it relatively easy to add new Subspaces. 55 80 struct Subspace { 56 std::array<MarkedAllocator, preciseCount> preciseAllocators; 57 std::array<MarkedAllocator, impreciseCount> impreciseAllocators; 58 MarkedAllocator largeAllocator; 81 std::array<MarkedAllocator*, numSizeClasses> allocatorForSizeStep; 82 83 // Each MarkedAllocator is a size class. 84 Bag<MarkedAllocator> bagOfAllocators; 85 86 AllocatorAttributes attributes; 59 87 }; 60 88 61 89 MarkedSpace(Heap*); 62 90 ~MarkedSpace(); 63 91 void lastChanceToFinalize(); 64 92 65 MarkedAllocator& allocatorFor(size_t); 66 MarkedAllocator& destructorAllocatorFor(size_t); 67 MarkedAllocator& auxiliaryAllocatorFor(size_t); 93 static size_t optimalSizeFor(size_t); 94 95 static MarkedAllocator* allocatorFor(Subspace&, size_t); 96 97 MarkedAllocator* allocatorFor(size_t); 98 MarkedAllocator* destructorAllocatorFor(size_t); 99 MarkedAllocator* auxiliaryAllocatorFor(size_t); 100 101 JS_EXPORT_PRIVATE void* allocate(Subspace&, size_t); 102 JS_EXPORT_PRIVATE void* tryAllocate(Subspace&, size_t); 103 68 104 void* allocateWithDestructor(size_t); 69 105 void* allocateWithoutDestructor(size_t); 70 106 void* allocateAuxiliary(size_t); 71 107 void* tryAllocateAuxiliary(size_t); 108 72 109 Subspace& subspaceForObjectsWithDestructor() { return m_destructorSpace; } 73 110 Subspace& subspaceForObjectsWithoutDestructor() { return m_normalSpace; } 74 111 Subspace& subspaceForAuxiliaryData() { return m_auxiliarySpace; } 75 112 76 113 void resetAllocators(); 77 114 … … 87 124 void stopAllocating(); 88 125 void resumeAllocating(); // If we just stopped allocation but we didn't do a collection, we need to resume allocation. 126 127 void prepareForMarking(); 89 128 90 129 typedef HashSet<MarkedBlock*>::iterator BlockIterator; … … 95 134 96 135 void shrink(); 97 void freeBlock(MarkedBlock *);98 void freeOrShrinkBlock(MarkedBlock *);99 100 void didAddBlock(MarkedBlock *);101 void didConsumeFreeList(MarkedBlock *);102 void didAllocateInBlock(MarkedBlock *);103 104 void clearMarks();136 void freeBlock(MarkedBlock::Handle*); 137 void freeOrShrinkBlock(MarkedBlock::Handle*); 138 139 void didAddBlock(MarkedBlock::Handle*); 140 void didConsumeFreeList(MarkedBlock::Handle*); 141 void didAllocateInBlock(MarkedBlock::Handle*); 142 143 void flip(); 105 144 void clearNewlyAllocated(); 106 145 void sweep(); 146 void sweepLargeAllocations(); 107 147 void zombifySweep(); 108 148 size_t objectCount(); … … 111 151 112 152 bool isPagedOut(double deadline); 113 114 const Vector<MarkedBlock*>& blocksWithNewObjects() const { return m_blocksWithNewObjects; } 153 154 uint64_t version() const { return m_version; } 155 156 const Vector<MarkedBlock::Handle*>& blocksWithNewObjects() const { return m_blocksWithNewObjects; } 157 158 const Vector<LargeAllocation*>& largeAllocations() const { return m_largeAllocations; } 159 unsigned largeAllocationsNurseryOffset() const { return m_largeAllocationsNurseryOffset; } 160 unsigned largeAllocationsOffsetForThisCollection() const { return m_largeAllocationsOffsetForThisCollection; } 161 162 // These are cached pointers and offsets for quickly searching the large allocations that are 163 // relevant to this collection. 164 LargeAllocation** largeAllocationsForThisCollectionBegin() const { return m_largeAllocationsForThisCollectionBegin; } 165 LargeAllocation** largeAllocationsForThisCollectionEnd() const { return m_largeAllocationsForThisCollectionEnd; } 166 unsigned largeAllocationsForThisCollectionSize() const { return m_largeAllocationsForThisCollectionSize; } 115 167 116 168 private: 117 169 friend class LLIntOffsetsExtractor; 118 170 friend class JIT; 171 friend class WeakSet; 172 173 JS_EXPORT_PRIVATE static std::array<size_t, numSizeClasses> s_sizeClassForSizeStep; 174 175 JS_EXPORT_PRIVATE void* allocateLarge(Subspace&, size_t); 176 JS_EXPORT_PRIVATE void* tryAllocateLarge(Subspace&, size_t); 177 178 static void initializeSizeClassForStepSize(); 179 180 void initializeSubspace(Subspace&); 119 181 120 182 template<typename Functor> void forEachAllocator(const Functor&); 121 183 template<typename Functor> void forEachSubspace(const Functor&); 122 MarkedAllocator& allocatorFor(Subspace&, size_t); 184 185 void addActiveWeakSet(WeakSet*); 123 186 124 187 Subspace m_destructorSpace; … … 127 190 128 191 Heap* m_heap; 192 uint64_t m_version { 42 }; // This can start at any value, including random garbage values. 129 193 size_t m_capacity; 130 194 bool m_isIterating; 131 195 MarkedBlockSet m_blocks; 132 Vector<MarkedBlock*> m_blocksWithNewObjects; 196 Vector<MarkedBlock::Handle*> m_blocksWithNewObjects; 197 Vector<LargeAllocation*> m_largeAllocations; 198 unsigned m_largeAllocationsNurseryOffset { 0 }; 199 unsigned m_largeAllocationsOffsetForThisCollection { 0 }; 200 unsigned m_largeAllocationsNurseryOffsetForSweep { 0 }; 201 LargeAllocation** m_largeAllocationsForThisCollectionBegin { nullptr }; 202 LargeAllocation** m_largeAllocationsForThisCollectionEnd { nullptr }; 203 unsigned m_largeAllocationsForThisCollectionSize { 0 }; 204 SentinelLinkedList<WeakSet, BasicRawSentinelNode<WeakSet>> m_activeWeakSets; 205 SentinelLinkedList<WeakSet, BasicRawSentinelNode<WeakSet>> m_newActiveWeakSets; 133 206 }; 134 207 … … 138 211 BlockIterator end = m_blocks.set().end(); 139 212 for (BlockIterator it = m_blocks.set().begin(); it != end; ++it) { 140 if ((*it)->forEachLiveCell(functor) == IterationStatus::Done) 141 break; 213 if ((*it)->handle().forEachLiveCell(functor) == IterationStatus::Done) 214 return; 215 } 216 for (LargeAllocation* allocation : m_largeAllocations) { 217 if (allocation->isLive()) { 218 if (functor(allocation->cell(), allocation->attributes().cellKind) == IterationStatus::Done) 219 return; 220 } 142 221 } 143 222 } … … 148 227 BlockIterator end = m_blocks.set().end(); 149 228 for (BlockIterator it = m_blocks.set().begin(); it != end; ++it) { 150 if ((*it)->forEachDeadCell(functor) == IterationStatus::Done) 151 break; 152 } 153 } 154 155 inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes) 229 if ((*it)->handle().forEachDeadCell(functor) == IterationStatus::Done) 230 return; 231 } 232 for (LargeAllocation* allocation : m_largeAllocations) { 233 if (!allocation->isLive()) { 234 if (functor(allocation->cell(), allocation->attributes().cellKind) == IterationStatus::Done) 235 return; 236 } 237 } 238 } 239 240 inline MarkedAllocator* MarkedSpace::allocatorFor(Subspace& space, size_t bytes) 241 { 242 ASSERT(bytes); 243 if (bytes <= largeCutoff) 244 return space.allocatorForSizeStep[sizeClassToIndex(bytes)]; 245 return nullptr; 246 } 247 248 inline MarkedAllocator* MarkedSpace::allocatorFor(size_t bytes) 156 249 { 157 250 return allocatorFor(m_normalSpace, bytes); 158 251 } 159 252 160 inline MarkedAllocator &MarkedSpace::destructorAllocatorFor(size_t bytes)253 inline MarkedAllocator* MarkedSpace::destructorAllocatorFor(size_t bytes) 161 254 { 162 255 return allocatorFor(m_destructorSpace, bytes); 163 256 } 164 257 165 inline MarkedAllocator &MarkedSpace::auxiliaryAllocatorFor(size_t bytes)258 inline MarkedAllocator* MarkedSpace::auxiliaryAllocatorFor(size_t bytes) 166 259 { 167 260 return allocatorFor(m_auxiliarySpace, bytes); … … 170 263 inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes) 171 264 { 172 return allocat orFor(bytes).allocate(bytes);265 return allocate(m_normalSpace, bytes); 173 266 } 174 267 175 268 inline void* MarkedSpace::allocateWithDestructor(size_t bytes) 176 269 { 177 return destructorAllocatorFor(bytes).allocate(bytes);270 return allocate(m_destructorSpace, bytes); 178 271 } 179 272 180 273 inline void* MarkedSpace::allocateAuxiliary(size_t bytes) 181 274 { 182 return auxiliaryAllocatorFor(bytes).allocate(bytes); 275 return allocate(m_auxiliarySpace, bytes); 276 } 277 278 inline void* MarkedSpace::tryAllocateAuxiliary(size_t bytes) 279 { 280 return tryAllocate(m_auxiliarySpace, bytes); 183 281 } 184 282 185 283 template <typename Functor> inline void MarkedSpace::forEachBlock(const Functor& functor) 284 { 285 forEachAllocator( 286 [&] (MarkedAllocator& allocator) -> IterationStatus { 287 allocator.forEachBlock(functor); 288 return IterationStatus::Continue; 289 }); 290 } 291 292 template <typename Functor> 293 void MarkedSpace::forEachAllocator(const Functor& functor) 186 294 { 187 295 forEachSubspace( 188 296 [&] (Subspace& subspace, AllocatorAttributes) -> IterationStatus { 189 for ( size_t i = 0; i < preciseCount; ++i)190 subspace.preciseAllocators[i].forEachBlock(functor);191 for (size_t i = 0; i < impreciseCount; ++i)192 subspace.impreciseAllocators[i].forEachBlock(functor);193 subspace.largeAllocator.forEachBlock(functor);297 for (MarkedAllocator* allocator : subspace.bagOfAllocators) { 298 if (functor(*allocator) == IterationStatus::Done) 299 return IterationStatus::Done; 300 } 301 194 302 return IterationStatus::Continue; 195 303 }); 196 }197 198 inline void MarkedSpace::didAddBlock(MarkedBlock* block)199 {200 m_capacity += block->capacity();201 m_blocks.add(block);202 }203 204 inline void MarkedSpace::didAllocateInBlock(MarkedBlock* block)205 {206 m_blocksWithNewObjects.append(block);207 }208 209 inline size_t MarkedSpace::objectCount()210 {211 size_t result = 0;212 forEachBlock(213 [&] (MarkedBlock* block) {214 result += block->markCount();215 });216 return result;217 }218 219 inline size_t MarkedSpace::size()220 {221 size_t result = 0;222 forEachBlock(223 [&] (MarkedBlock* block) {224 result += block->markCount() * block->cellSize();225 });226 return result;227 }228 229 inline size_t MarkedSpace::capacity()230 {231 return m_capacity;232 304 } 233 305 … … 252 324 } 253 325 254 inline MarkedAllocator& MarkedSpace::allocatorFor(Subspace& space,size_t bytes)326 ALWAYS_INLINE size_t MarkedSpace::optimalSizeFor(size_t bytes) 255 327 { 256 328 ASSERT(bytes); 257 329 if (bytes <= preciseCutoff) 258 return space.preciseAllocators[(bytes - 1) / preciseStep];259 if (bytes <= impreciseCutoff)260 return s pace.impreciseAllocators[(bytes - 1) / impreciseStep];261 return space.largeAllocator;330 return WTF::roundUpToMultipleOf<sizeStep>(bytes); 331 if (bytes <= largeCutoff) 332 return s_sizeClassForSizeStep[sizeClassToIndex(bytes)]; 333 return bytes; 262 334 } 263 335 -
trunk/Source/JavaScriptCore/heap/SlotVisitor.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "CopiedSpace.h" 33 33 #include "CopiedSpaceInlines.h" 34 #include "HeapCellInlines.h" 34 35 #include "HeapProfiler.h" 35 36 #include "HeapSnapshotBuilder.h" 36 37 #include "JSArray.h" 37 38 #include "JSDestructibleObject.h" 38 #include "VM.h"39 39 #include "JSObject.h" 40 40 #include "JSString.h" 41 41 #include "JSCInlines.h" 42 #include "SuperSampler.h" 43 #include "VM.h" 42 44 #include <wtf/Lock.h> 43 45 … … 80 82 , m_visitCount(0) 81 83 , m_isInParallelMode(false) 84 , m_version(42) 82 85 , m_heap(heap) 83 86 #if !ASSERT_DISABLED … … 97 100 if (heap()->operationInProgress() == FullCollection) 98 101 ASSERT(m_opaqueRoots.isEmpty()); // Should have merged by now. 102 else 103 reset(); 99 104 100 105 if (HeapProfiler* heapProfiler = vm().heapProfiler()) 101 106 m_heapSnapshotBuilder = heapProfiler->activeSnapshotBuilder(); 107 108 m_version = heap()->objectSpace().version(); 102 109 } 103 110 … … 109 116 m_heapSnapshotBuilder = nullptr; 110 117 ASSERT(!m_currentCell); 111 ASSERT(m_stack.isEmpty());112 118 } 113 119 … … 119 125 void SlotVisitor::append(ConservativeRoots& conservativeRoots) 120 126 { 121 JSCell** roots = conservativeRoots.roots();127 HeapCell** roots = conservativeRoots.roots(); 122 128 size_t size = conservativeRoots.size(); 123 129 for (size_t i = 0; i < size; ++i) 124 append(roots[i]); 130 appendJSCellOrAuxiliary(roots[i]); 131 } 132 133 void SlotVisitor::appendJSCellOrAuxiliary(HeapCell* heapCell) 134 { 135 if (!heapCell) 136 return; 137 138 ASSERT(!m_isCheckingForDefaultMarkViolation); 139 140 if (Heap::testAndSetMarked(m_version, heapCell)) 141 return; 142 143 switch (heapCell->cellKind()) { 144 case HeapCell::JSCell: { 145 JSCell* jsCell = static_cast<JSCell*>(heapCell); 146 147 if (!jsCell->structure()) { 148 ASSERT_NOT_REACHED(); 149 return; 150 } 151 152 jsCell->setCellState(CellState::NewGrey); 153 154 appendToMarkStack(jsCell); 155 return; 156 } 157 158 case HeapCell::Auxiliary: { 159 noteLiveAuxiliaryCell(heapCell); 160 return; 161 } } 125 162 } 126 163 … … 146 183 void SlotVisitor::setMarkedAndAppendToMarkStack(JSCell* cell) 147 184 { 185 SuperSamplerScope superSamplerScope(false); 186 148 187 ASSERT(!m_isCheckingForDefaultMarkViolation); 149 188 if (!cell) … … 153 192 validate(cell); 154 193 #endif 155 156 if (Heap::testAndSetMarked(cell) || !cell->structure()) { 157 ASSERT(cell->structure()); 158 return; 159 } 160 194 195 if (cell->isLargeAllocation()) 196 setMarkedAndAppendToMarkStack(cell->largeAllocation(), cell); 197 else 198 setMarkedAndAppendToMarkStack(cell->markedBlock(), cell); 199 } 200 201 template<typename ContainerType> 202 ALWAYS_INLINE void SlotVisitor::setMarkedAndAppendToMarkStack(ContainerType& container, JSCell* cell) 203 { 204 container.flipIfNecessaryConcurrently(m_version); 205 206 if (container.testAndSetMarked(cell)) 207 return; 208 209 ASSERT(cell->structure()); 210 161 211 // Indicate that the object is grey and that: 162 212 // In case of concurrent GC: it's the first time it is grey in this GC cycle. 163 213 // In case of eden collection: it's a new object that became grey rather than an old remembered object. 164 214 cell->setCellState(CellState::NewGrey); 165 166 appendToMarkStack(c ell);215 216 appendToMarkStack(container, cell); 167 217 } 168 218 169 219 void SlotVisitor::appendToMarkStack(JSCell* cell) 220 { 221 if (cell->isLargeAllocation()) 222 appendToMarkStack(cell->largeAllocation(), cell); 223 else 224 appendToMarkStack(cell->markedBlock(), cell); 225 } 226 227 template<typename ContainerType> 228 ALWAYS_INLINE void SlotVisitor::appendToMarkStack(ContainerType& container, JSCell* cell) 170 229 { 171 230 ASSERT(Heap::isMarked(cell)); 172 231 ASSERT(!cell->isZapped()); 173 232 233 container.noteMarked(); 234 235 // FIXME: These "just work" because the GC resets these fields before doing anything else. But 236 // that won't be the case when we do concurrent GC. 174 237 m_visitCount++; 175 m_bytesVisited += MarkedBlock::blockFor(cell)->cellSize(); 238 m_bytesVisited += container.cellSize(); 239 176 240 m_stack.append(cell); 177 241 178 242 if (UNLIKELY(m_heapSnapshotBuilder)) 179 243 m_heapSnapshotBuilder->appendNode(cell); 244 } 245 246 void SlotVisitor::markAuxiliary(const void* base) 247 { 248 HeapCell* cell = bitwise_cast<HeapCell*>(base); 249 250 if (Heap::testAndSetMarked(m_version, cell)) { 251 RELEASE_ASSERT(Heap::isMarked(cell)); 252 return; 253 } 254 255 noteLiveAuxiliaryCell(cell); 256 } 257 258 void SlotVisitor::noteLiveAuxiliaryCell(HeapCell* cell) 259 { 260 // We get here once per GC under these circumstances: 261 // 262 // Eden collection: if the cell was allocated since the last collection and is live somehow. 263 // 264 // Full collection: if the cell is live somehow. 265 266 CellContainer container = cell->cellContainer(); 267 268 container.noteMarked(); 269 270 m_visitCount++; 271 m_bytesVisited += container.cellSize(); 180 272 } 181 273 … … 203 295 { 204 296 ASSERT(Heap::isMarked(cell)); 205 297 206 298 SetCurrentCellScope currentCellScope(*this, cell); 207 299 208 300 m_currentObjectCellStateBeforeVisiting = cell->cellState(); 209 301 cell->setCellState(CellState::OldBlack); -
trunk/Source/JavaScriptCore/heap/SlotVisitor.h
r204912 r205462 38 38 class GCThreadSharedData; 39 39 class Heap; 40 class HeapCell; 40 41 class HeapSnapshotBuilder; 41 42 template<typename T> class JITWriteBarrier; 43 class MarkedBlock; 42 44 class UnconditionalFinalizer; 43 45 template<typename T> class Weak; … … 105 107 void harvestWeakReferences(); 106 108 void finalizeUnconditionalFinalizers(); 109 110 // This informs the GC about auxiliary of some size that we are keeping alive. If you don't do 111 // this then the space will be freed at end of GC. 112 void markAuxiliary(const void* base); 107 113 108 114 void copyLater(JSCell*, CopyToken, void*, size_t); … … 124 130 125 131 JS_EXPORT_PRIVATE void append(JSValue); // This is private to encourage clients to use WriteBarrier<T>. 132 void appendJSCellOrAuxiliary(HeapCell*); 126 133 void appendHidden(JSValue); 127 134 128 135 JS_EXPORT_PRIVATE void setMarkedAndAppendToMarkStack(JSCell*); 136 137 template<typename ContainerType> 138 void setMarkedAndAppendToMarkStack(ContainerType&, JSCell*); 139 129 140 void appendToMarkStack(JSCell*); 141 142 template<typename ContainerType> 143 void appendToMarkStack(ContainerType&, JSCell*); 144 145 void noteLiveAuxiliaryCell(HeapCell*); 130 146 131 147 JS_EXPORT_PRIVATE void mergeOpaqueRoots(); … … 144 160 size_t m_visitCount; 145 161 bool m_isInParallelMode; 162 163 uint64_t m_version; 146 164 147 165 Heap& m_heap; -
trunk/Source/JavaScriptCore/heap/WeakBlock.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "WeakBlock.h" 28 28 29 #include "CellContainerInlines.h" 29 30 #include "Heap.h" 30 31 #include "HeapRootVisitor.h" … … 35 36 namespace JSC { 36 37 37 WeakBlock* WeakBlock::create(Heap& heap, MarkedBlock& markedBlock)38 WeakBlock* WeakBlock::create(Heap& heap, CellContainer container) 38 39 { 39 40 heap.didAllocateBlock(WeakBlock::blockSize); 40 return new (NotNull, fastMalloc(blockSize)) WeakBlock( markedBlock);41 return new (NotNull, fastMalloc(blockSize)) WeakBlock(container); 41 42 } 42 43 … … 48 49 } 49 50 50 WeakBlock::WeakBlock( MarkedBlock& markedBlock)51 WeakBlock::WeakBlock(CellContainer container) 51 52 : DoublyLinkedListNode<WeakBlock>() 52 , m_ markedBlock(&markedBlock)53 , m_container(container) 53 54 { 54 55 for (size_t i = 0; i < weakImplCount(); ++i) { … … 102 103 return; 103 104 104 // If this WeakBlock doesn't belong to a MarkedBlock, we won't even be here. 105 ASSERT(m_markedBlock); 105 // If this WeakBlock doesn't belong to a CellContainer, we won't even be here. 106 ASSERT(m_container); 107 108 m_container.flipIfNecessary(); 106 109 107 110 // We only visit after marking. 108 ASSERT(m_ markedBlock->isMarkedOrRetired());111 ASSERT(m_container.isMarked()); 109 112 110 113 SlotVisitor& visitor = heapRootVisitor.visitor(); … … 120 123 121 124 const JSValue& jsValue = weakImpl->jsValue(); 122 if (m_ markedBlock->isMarkedOrNewlyAllocated(jsValue.asCell()))125 if (m_container.isMarkedOrNewlyAllocated(jsValue.asCell())) 123 126 continue; 124 127 125 128 if (!weakHandleOwner->isReachableFromOpaqueRoots(Handle<Unknown>::wrapSlot(&const_cast<JSValue&>(jsValue)), weakImpl->context(), visitor)) 126 129 continue; … … 136 139 return; 137 140 138 // If this WeakBlock doesn't belong to a MarkedBlock, we won't even be here. 139 ASSERT(m_markedBlock); 141 // If this WeakBlock doesn't belong to a CellContainer, we won't even be here. 142 ASSERT(m_container); 143 144 m_container.flipIfNecessary(); 140 145 141 146 // We only reap after marking. 142 ASSERT(m_ markedBlock->isMarkedOrRetired());147 ASSERT(m_container.isMarked()); 143 148 144 149 for (size_t i = 0; i < weakImplCount(); ++i) { … … 147 152 continue; 148 153 149 if (m_ markedBlock->isMarkedOrNewlyAllocated(weakImpl->jsValue().asCell())) {154 if (m_container.isMarkedOrNewlyAllocated(weakImpl->jsValue().asCell())) { 150 155 ASSERT(weakImpl->state() == WeakImpl::Live); 151 156 continue; -
trunk/Source/JavaScriptCore/heap/WeakBlock.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #define WeakBlock_h 28 28 29 #include "CellContainer.h" 29 30 #include "WeakImpl.h" 30 31 #include <wtf/DoublyLinkedList.h> … … 35 36 class Heap; 36 37 class HeapRootVisitor; 37 class MarkedBlock;38 38 39 39 class WeakBlock : public DoublyLinkedListNode<WeakBlock> { 40 40 public: 41 41 friend class WTF::DoublyLinkedListNode<WeakBlock>; 42 static const size_t blockSize = 1 * KB; // 1/16 of MarkedBlock size42 static const size_t blockSize = 256; // 1/16 of MarkedBlock size 43 43 44 44 struct FreeCell { … … 54 54 }; 55 55 56 static WeakBlock* create(Heap&, MarkedBlock&);56 static WeakBlock* create(Heap&, CellContainer); 57 57 static void destroy(Heap&, WeakBlock*); 58 58 … … 69 69 70 70 void lastChanceToFinalize(); 71 void disconnect MarkedBlock() { m_markedBlock = nullptr; }71 void disconnectContainer() { m_container = CellContainer(); } 72 72 73 73 private: 74 74 static FreeCell* asFreeCell(WeakImpl*); 75 75 76 explicit WeakBlock( MarkedBlock&);76 explicit WeakBlock(CellContainer); 77 77 void finalize(WeakImpl*); 78 78 WeakImpl* weakImpls(); … … 80 80 void addToFreeList(FreeCell**, WeakImpl*); 81 81 82 MarkedBlock* m_markedBlock;82 CellContainer m_container; 83 83 WeakBlock* m_prev; 84 84 WeakBlock* m_next; -
trunk/Source/JavaScriptCore/heap/WeakSet.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 35 35 WeakSet::~WeakSet() 36 36 { 37 if (isOnList()) 38 remove(); 39 37 40 Heap& heap = *this->heap(); 38 41 WeakBlock* next = 0; … … 54 57 // If this WeakBlock is logically empty, but still has Weaks pointing into it, 55 58 // we can't destroy it just yet. Detach it from the WeakSet and hand ownership 56 // to the Heap so we don't pin down the entire 64kB MarkedBlock.59 // to the Heap so we don't pin down the entire MarkedBlock or LargeAllocation. 57 60 m_blocks.remove(block); 58 61 heap()->addLogicallyEmptyWeakBlock(block); 59 block->disconnect MarkedBlock();62 block->disconnectContainer(); 60 63 } 61 64 block = nextBlock; … … 63 66 64 67 resetAllocator(); 68 } 69 70 void WeakSet::shrink() 71 { 72 WeakBlock* next; 73 for (WeakBlock* block = m_blocks.head(); block; block = next) { 74 next = block->next(); 75 76 if (block->isEmpty()) 77 removeAllocator(block); 78 } 79 80 resetAllocator(); 81 82 if (m_blocks.isEmpty() && isOnList()) 83 remove(); 65 84 } 66 85 … … 89 108 WeakBlock::FreeCell* WeakSet::addAllocator() 90 109 { 91 WeakBlock* block = WeakBlock::create(*heap(), m_markedBlock); 110 if (m_blocks.isEmpty() && !isOnList()) 111 heap()->objectSpace().addActiveWeakSet(this); 112 113 WeakBlock* block = WeakBlock::create(*heap(), m_container); 92 114 heap()->didAllocate(WeakBlock::blockSize); 93 115 m_blocks.append(block); -
trunk/Source/JavaScriptCore/heap/WeakSet.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #define WeakSet_h 28 28 29 #include "CellContainer.h" 29 30 #include "WeakBlock.h" 31 #include <wtf/SentinelLinkedList.h> 30 32 31 33 namespace JSC { 32 34 33 35 class Heap; 34 class MarkedBlock;35 36 class WeakImpl; 36 37 37 class WeakSet {38 class WeakSet : public BasicRawSentinelNode<WeakSet> { 38 39 friend class LLIntOffsetsExtractor; 39 40 … … 42 43 static void deallocate(WeakImpl*); 43 44 44 WeakSet(VM*, MarkedBlock&);45 WeakSet(VM*, CellContainer); 45 46 ~WeakSet(); 46 47 void lastChanceToFinalize(); 48 49 CellContainer container() const { return m_container; } 50 void setContainer(CellContainer container) { m_container = container; } 47 51 48 52 Heap* heap() const; … … 51 55 bool isEmpty() const; 52 56 53 void visit(HeapRootVisitor&);57 unsigned visit(HeapRootVisitor&); 54 58 void reap(); 55 59 void sweep(); … … 67 71 DoublyLinkedList<WeakBlock> m_blocks; 68 72 VM* m_vm; 69 MarkedBlock& m_markedBlock;73 CellContainer m_container; 70 74 }; 71 75 72 inline WeakSet::WeakSet(VM* vm, MarkedBlock& markedBlock)76 inline WeakSet::WeakSet(VM* vm, CellContainer container) 73 77 : m_allocator(0) 74 78 , m_nextAllocator(0) 75 79 , m_vm(vm) 76 , m_ markedBlock(markedBlock)80 , m_container(container) 77 81 { 78 82 } … … 104 108 } 105 109 106 inline void WeakSet::visit(HeapRootVisitor& visitor)110 inline unsigned WeakSet::visit(HeapRootVisitor& visitor) 107 111 { 108 for (WeakBlock* block = m_blocks.head(); block; block = block->next()) 112 unsigned count = 0; 113 for (WeakBlock* block = m_blocks.head(); block; block = block->next()) { 114 count++; 109 115 block->visit(visitor); 116 } 117 return count; 110 118 } 111 119 … … 114 122 for (WeakBlock* block = m_blocks.head(); block; block = block->next()) 115 123 block->reap(); 116 }117 118 inline void WeakSet::shrink()119 {120 WeakBlock* next;121 for (WeakBlock* block = m_blocks.head(); block; block = next) {122 next = block->next();123 124 if (block->isEmpty())125 removeAllocator(block);126 }127 128 resetAllocator();129 124 } 130 125 -
trunk/Source/JavaScriptCore/heap/WeakSetInlines.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #define WeakSetInlines_h 28 28 29 #include "CellContainerInlines.h" 29 30 #include "MarkedBlock.h" 30 31 … … 33 34 inline WeakImpl* WeakSet::allocate(JSValue jsValue, WeakHandleOwner* weakHandleOwner, void* context) 34 35 { 35 WeakSet& weakSet = MarkedBlock::blockFor(jsValue.asCell())->weakSet();36 WeakSet& weakSet = jsValue.asCell()->cellContainer().weakSet(); 36 37 WeakBlock::FreeCell* allocator = weakSet.m_allocator; 37 38 if (UNLIKELY(!allocator)) -
trunk/Source/JavaScriptCore/inspector/InjectedScriptManager.cpp
r204912 r205462 36 36 #include "InjectedScriptSource.h" 37 37 #include "InspectorValues.h" 38 #include "JSCInlines.h" 38 39 #include "JSInjectedScriptHost.h" 39 40 #include "JSLock.h" -
trunk/Source/JavaScriptCore/inspector/JSGlobalObjectInspectorController.cpp
r205091 r205462 39 39 #include "InspectorHeapAgent.h" 40 40 #include "InspectorScriptProfilerAgent.h" 41 #include "JSCInlines.h" 41 42 #include "JSGlobalObject.h" 42 43 #include "JSGlobalObjectConsoleAgent.h" -
trunk/Source/JavaScriptCore/inspector/JSJavaScriptCallFrame.cpp
r205198 r205462 30 30 #include "Error.h" 31 31 #include "IdentifierInlines.h" 32 #include "JSCJSValue.h" 33 #include "JSCellInlines.h" 32 #include "JSCInlines.h" 34 33 #include "JSJavaScriptCallFramePrototype.h" 35 34 #include "ObjectConstructor.h" 36 #include "StructureInlines.h"37 35 38 36 using namespace JSC; -
trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp
r204912 r205462 35 35 #include "DebuggerScope.h" 36 36 #include "Exception.h" 37 #include "JSCInlines.h" 37 38 #include "JSJavaScriptCallFrame.h" 38 39 #include "JSLock.h" -
trunk/Source/JavaScriptCore/inspector/agents/InspectorDebuggerAgent.cpp
r204912 r205462 36 36 #include "InspectorFrontendRouter.h" 37 37 #include "InspectorValues.h" 38 #include "JSCInlines.h" 38 39 #include "RegularExpression.h" 39 40 #include "ScriptDebugServer.h" -
trunk/Source/JavaScriptCore/interpreter/CachedCall.h
r205198 r205462 43 43 : m_valid(false) 44 44 , m_interpreter(callFrame->interpreter()) 45 , m_entryScope(callFrame->vm(), function->scope()->globalObject()) 45 , m_vm(callFrame->vm()) 46 , m_entryScope(m_vm, function->scope()->globalObject(m_vm)) 46 47 { 47 48 VM& vm = m_entryScope.vm(); … … 68 69 bool m_valid; 69 70 Interpreter* m_interpreter; 71 VM& m_vm; 70 72 VMEntryScope m_entryScope; 71 73 ProtoCallFrame m_protoCallFrame; -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r205324 r205462 52 52 #include "JSWithScope.h" 53 53 #include "LLIntCLoop.h" 54 #include "LLIntData.h" 54 55 #include "LLIntThunks.h" 55 56 #include "LiteralParser.h" … … 85 86 86 87 namespace JSC { 87 88 intptr_t StackFrame::sourceID() const89 {90 if (!codeBlock)91 return noSourceID;92 return codeBlock->ownerScriptExecutable()->sourceID();93 }94 95 String StackFrame::sourceURL() const96 {97 if (!codeBlock)98 return ASCIILiteral("[native code]");99 100 String sourceURL = codeBlock->ownerScriptExecutable()->sourceURL();101 if (!sourceURL.isNull())102 return sourceURL;103 return emptyString();104 }105 106 String StackFrame::functionName(VM& vm) const107 {108 if (codeBlock) {109 switch (codeBlock->codeType()) {110 case EvalCode:111 return ASCIILiteral("eval code");112 case ModuleCode:113 return ASCIILiteral("module code");114 case FunctionCode:115 break;116 case GlobalCode:117 return ASCIILiteral("global code");118 default:119 ASSERT_NOT_REACHED();120 }121 }122 String name;123 if (callee)124 name = getCalculatedDisplayName(vm, callee.get()).impl();125 return name.isNull() ? emptyString() : name;126 }127 88 128 89 JSValue eval(CallFrame* callFrame) … … 275 236 276 237 JSCell* cell = arguments.asCell(); 238 277 239 switch (cell->type()) { 278 240 case DirectArgumentsType: … … 481 443 return opcode >= 0 && opcode <= op_end; 482 444 #endif 483 }484 485 void StackFrame::computeLineAndColumn(unsigned& line, unsigned& column) const486 {487 if (!codeBlock) {488 line = 0;489 column = 0;490 return;491 }492 493 int divot = 0;494 int unusedStartOffset = 0;495 int unusedEndOffset = 0;496 codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divot, unusedStartOffset, unusedEndOffset, line, column);497 498 ScriptExecutable* executable = codeBlock->ownerScriptExecutable();499 if (executable->hasOverrideLineNumber())500 line = executable->overrideLineNumber();501 }502 503 String StackFrame::toString(VM& vm) const504 {505 StringBuilder traceBuild;506 String functionName = this->functionName(vm);507 String sourceURL = this->sourceURL();508 traceBuild.append(functionName);509 if (!sourceURL.isEmpty()) {510 if (!functionName.isEmpty())511 traceBuild.append('@');512 traceBuild.append(sourceURL);513 if (codeBlock) {514 unsigned line;515 unsigned column;516 computeLineAndColumn(line, column);517 518 traceBuild.append(':');519 traceBuild.appendNumber(line);520 traceBuild.append(':');521 traceBuild.appendNumber(column);522 }523 }524 return traceBuild.toString().impl();525 445 } 526 446 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r204994 r205462 38 38 #include "SourceProvider.h" 39 39 #include "StackAlignment.h" 40 #include "StackFrame.h" 40 41 #include <wtf/HashMap.h> 41 42 #include <wtf/text/StringBuilder.h> … … 68 69 struct UnlinkedInstruction; 69 70 70 enum UnwindStart { UnwindFromCurrentFrame, UnwindFromCallerFrame };71 enum UnwindStart : uint8_t { UnwindFromCurrentFrame, UnwindFromCallerFrame }; 71 72 72 73 enum DebugHookID { … … 85 86 StackFrameFunctionCode, 86 87 StackFrameNativeCode 87 };88 89 struct StackFrame {90 Strong<JSObject> callee;91 Strong<CodeBlock> codeBlock;92 unsigned bytecodeOffset;93 94 bool isNative() const { return !codeBlock; }95 96 void computeLineAndColumn(unsigned& line, unsigned& column) const;97 String functionName(VM&) const;98 intptr_t sourceID() const;99 String sourceURL() const;100 String toString(VM&) const;101 88 }; 102 89 -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h
r204912 r205462 1406 1406 void emitRandomThunk(GPRReg scratch0, GPRReg scratch1, GPRReg scratch2, GPRReg scratch3, FPRReg result); 1407 1407 #endif 1408 1409 void emitAllocate(GPRReg resultGPR, GPRReg allocatorGPR, GPRReg scratchGPR, JumpList& slowPath) 1410 { 1411 if (Options::forceGCSlowPaths()) 1408 1409 // Call this if you know that the value held in allocatorGPR is non-null. This DOES NOT mean 1410 // that allocator is non-null; allocator can be null as a signal that we don't know what the 1411 // value of allocatorGPR is. 1412 void emitAllocateWithNonNullAllocator(GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, GPRReg scratchGPR, JumpList& slowPath) 1413 { 1414 // NOTE: This is carefully written so that we can call it while we disallow scratch 1415 // register usage. 1416 1417 if (Options::forceGCSlowPaths()) { 1412 1418 slowPath.append(jump()); 1419 return; 1420 } 1421 1422 Jump popPath; 1423 Jump done; 1424 1425 load32(Address(allocatorGPR, MarkedAllocator::offsetOfFreeList() + OBJECT_OFFSETOF(FreeList, remaining)), resultGPR); 1426 popPath = branchTest32(Zero, resultGPR); 1427 if (allocator) 1428 add32(TrustedImm32(-allocator->cellSize()), resultGPR, scratchGPR); 1413 1429 else { 1414 loadPtr(Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR); 1415 slowPath.append(branchTestPtr(Zero, resultGPR)); 1416 } 1430 move(resultGPR, scratchGPR); 1431 sub32(Address(allocatorGPR, MarkedAllocator::offsetOfCellSize()), scratchGPR); 1432 } 1433 negPtr(resultGPR); 1434 store32(scratchGPR, Address(allocatorGPR, MarkedAllocator::offsetOfFreeList() + OBJECT_OFFSETOF(FreeList, remaining))); 1435 Address payloadEndAddr = Address(allocatorGPR, MarkedAllocator::offsetOfFreeList() + OBJECT_OFFSETOF(FreeList, payloadEnd)); 1436 if (isX86()) 1437 addPtr(payloadEndAddr, resultGPR); 1438 else { 1439 loadPtr(payloadEndAddr, scratchGPR); 1440 addPtr(scratchGPR, resultGPR); 1441 } 1442 1443 done = jump(); 1444 1445 popPath.link(this); 1446 1447 loadPtr(Address(allocatorGPR, MarkedAllocator::offsetOfFreeList() + OBJECT_OFFSETOF(FreeList, head)), resultGPR); 1448 slowPath.append(branchTestPtr(Zero, resultGPR)); 1417 1449 1418 1450 // The object is half-allocated: we have what we know is a fresh object, but 1419 1451 // it's still on the GC's free list. 1420 1452 loadPtr(Address(resultGPR), scratchGPR); 1421 storePtr(scratchGPR, Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead())); 1453 storePtr(scratchGPR, Address(allocatorGPR, MarkedAllocator::offsetOfFreeList() + OBJECT_OFFSETOF(FreeList, head))); 1454 1455 done.link(this); 1456 } 1457 1458 void emitAllocate(GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, GPRReg scratchGPR, JumpList& slowPath) 1459 { 1460 if (!allocator) 1461 slowPath.append(branchTestPtr(Zero, allocatorGPR)); 1462 emitAllocateWithNonNullAllocator(resultGPR, allocator, allocatorGPR, scratchGPR, slowPath); 1422 1463 } 1423 1464 1424 1465 template<typename StructureType> 1425 void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure, GPRReg scratchGPR, JumpList& slowPath)1426 { 1427 emitAllocate(resultGPR, allocator GPR, scratchGPR, slowPath);1466 void emitAllocateJSCell(GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, StructureType structure, GPRReg scratchGPR, JumpList& slowPath) 1467 { 1468 emitAllocate(resultGPR, allocator, allocatorGPR, scratchGPR, slowPath); 1428 1469 emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR); 1429 1470 } 1430 1471 1431 1472 template<typename StructureType, typename StorageType> 1432 void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure, StorageType storage, GPRReg scratchGPR, JumpList& slowPath)1433 { 1434 emitAllocateJSCell(resultGPR, allocator GPR, structure, scratchGPR, slowPath);1473 void emitAllocateJSObject(GPRReg resultGPR, MarkedAllocator* allocator, GPRReg allocatorGPR, StructureType structure, StorageType storage, GPRReg scratchGPR, JumpList& slowPath) 1474 { 1475 emitAllocateJSCell(resultGPR, allocator, allocatorGPR, structure, scratchGPR, slowPath); 1435 1476 storePtr(storage, Address(resultGPR, JSObject::butterflyOffset())); 1436 1477 } … … 1441 1482 GPRReg scratchGPR2, JumpList& slowPath, size_t size) 1442 1483 { 1443 MarkedAllocator* allocator = &vm()->heap.allocatorForObjectOfType<ClassType>(size); 1484 MarkedAllocator* allocator = vm()->heap.allocatorForObjectOfType<ClassType>(size); 1485 if (!allocator) { 1486 slowPath.append(jump()); 1487 return; 1488 } 1444 1489 move(TrustedImmPtr(allocator), scratchGPR1); 1445 emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);1490 emitAllocateJSObject(resultGPR, allocator, scratchGPR1, structure, storage, scratchGPR2, slowPath); 1446 1491 } 1447 1492 … … 1452 1497 } 1453 1498 1499 // allocationSize can be aliased with any of the other input GPRs. If it's not aliased then it 1500 // won't be clobbered. 1454 1501 void emitAllocateVariableSized(GPRReg resultGPR, MarkedSpace::Subspace& subspace, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, JumpList& slowPath) 1455 1502 { 1456 static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two."); 1457 static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two."); 1458 1459 add32(TrustedImm32(MarkedSpace::preciseStep - 1), allocationSize); 1460 Jump notSmall = branch32(AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::preciseCutoff)); 1461 rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::preciseStep)), scratchGPR1); 1462 mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1); 1463 addPtr(TrustedImmPtr(&subspace.preciseAllocators[0]), scratchGPR1); 1464 1465 Jump selectedSmallSpace = jump(); 1466 notSmall.link(this); 1467 slowPath.append(branch32(AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::impreciseCutoff))); 1468 rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::impreciseStep)), scratchGPR1); 1469 mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1); 1470 addPtr(TrustedImmPtr(&subspace.impreciseAllocators[0]), scratchGPR1); 1471 1472 selectedSmallSpace.link(this); 1473 1474 emitAllocate(resultGPR, scratchGPR1, scratchGPR2, slowPath); 1503 static_assert(!(MarkedSpace::sizeStep & (MarkedSpace::sizeStep - 1)), "MarkedSpace::sizeStep must be a power of two."); 1504 1505 unsigned stepShift = getLSBSet(MarkedSpace::sizeStep); 1506 1507 add32(TrustedImm32(MarkedSpace::sizeStep - 1), allocationSize, scratchGPR1); 1508 urshift32(TrustedImm32(stepShift), scratchGPR1); 1509 slowPath.append(branch32(Above, scratchGPR1, TrustedImm32(MarkedSpace::largeCutoff >> stepShift))); 1510 move(TrustedImmPtr(&subspace.allocatorForSizeStep[0] - 1), scratchGPR2); 1511 loadPtr(BaseIndex(scratchGPR2, scratchGPR1, timesPtr()), scratchGPR1); 1512 1513 emitAllocate(resultGPR, nullptr, scratchGPR1, scratchGPR2, slowPath); 1475 1514 } 1476 1515 -
trunk/Source/JavaScriptCore/jit/CCallHelpers.h
r203600 r205462 289 289 290 290 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2, TrustedImm32 arg3) 291 { 292 resetCallArguments(); 293 addCallArgument(GPRInfo::callFrameRegister); 294 addCallArgument(arg1); 295 addCallArgument(arg2); 296 addCallArgument(arg3); 297 } 298 299 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2, GPRReg arg3) 291 300 { 292 301 resetCallArguments(); … … 1409 1418 } 1410 1419 1420 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2, GPRReg arg3) 1421 { 1422 move(arg3, GPRInfo::argumentGPR3); 1423 move(arg1, GPRInfo::argumentGPR1); 1424 move(arg2, GPRInfo::argumentGPR2); 1425 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 1426 } 1427 1411 1428 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2, TrustedImm32 arg3) 1412 1429 { -
trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp
r204912 r205462 33 33 #include "Heap.h" 34 34 #include "VM.h" 35 #include "JITStubRoutineSet.h" 35 36 #include "JSCInlines.h" 36 37 #include "SlotVisitor.h" … … 46 47 , m_isJettisoned(false) 47 48 { 48 vm.heap.m_jitStubRoutines .add(this);49 vm.heap.m_jitStubRoutines->add(this); 49 50 } 50 51 -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r204994 r205462 49 49 #include "TypeProfilerLog.h" 50 50 #include <wtf/CryptographicallyRandomNumber.h> 51 #include <wtf/SimpleStats.h> 51 52 52 53 using namespace std; … … 65 66 CodeLocationCall(MacroAssemblerCodePtr(returnAddress)), 66 67 newCalleeFunction); 68 } 69 70 JIT::CodeRef JIT::compileCTINativeCall(VM* vm, NativeFunction func) 71 { 72 if (!vm->canUseJIT()) 73 return CodeRef::createLLIntCodeRef(llint_native_call_trampoline); 74 JIT jit(vm, 0); 75 return jit.privateCompileCTINativeCall(vm, func); 67 76 } 68 77 … … 787 796 ("Baseline JIT code for %s", toCString(CodeBlockWithJITType(m_codeBlock, JITCode::BaselineJIT)).data())); 788 797 789 m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT .add(798 m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->add( 790 799 static_cast<double>(result.size()) / 791 800 static_cast<double>(m_instructions.size())); -
trunk/Source/JavaScriptCore/jit/JIT.h
r204994 r205462 41 41 #include "CodeBlock.h" 42 42 #include "CompactJITCodeMap.h" 43 #include "Interpreter.h"44 43 #include "JITDisassembler.h" 45 44 #include "JITInlineCacheGenerator.h" 46 45 #include "JITMathIC.h" 47 46 #include "JSInterfaceJIT.h" 48 #include "Opcode.h"49 47 #include "PCToCodeOriginMap.h" 50 48 #include "UnusedPointer.h" 51 49 52 50 namespace JSC { 51 52 enum OpcodeID : unsigned; 53 53 54 54 class ArrayAllocationProfile; … … 249 249 } 250 250 251 static CodeRef compileCTINativeCall(VM* vm, NativeFunction func) 252 { 253 if (!vm->canUseJIT()) { 254 return CodeRef::createLLIntCodeRef(llint_native_call_trampoline); 255 } 256 JIT jit(vm, 0); 257 return jit.privateCompileCTINativeCall(vm, func); 258 } 251 static CodeRef compileCTINativeCall(VM*, NativeFunction); 259 252 260 253 static unsigned frameRegisterCountFor(CodeBlock*); -
trunk/Source/JavaScriptCore/jit/JITExceptions.cpp
r204912 r205462 91 91 } 92 92 93 void genericUnwind(VM* vm, ExecState* callFrame) 94 { 95 genericUnwind(vm, callFrame, UnwindFromCurrentFrame); 96 } 97 93 98 } // namespace JSC -
trunk/Source/JavaScriptCore/jit/JITExceptions.h
r204912 r205462 27 27 #define JITExceptions_h 28 28 29 #include "Interpreter.h" 30 #include "JSCJSValue.h" 29 namespace JSC { 31 30 32 namespace JSC { 31 enum UnwindStart : uint8_t; 33 32 34 33 class ExecState; 35 34 class VM; 36 35 37 void genericUnwind(VM*, ExecState*, UnwindStart = UnwindFromCurrentFrame); 36 void genericUnwind(VM*, ExecState*, UnwindStart); 37 void genericUnwind(VM*, ExecState*); 38 38 39 39 } // namespace JSC -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r204994 r205462 33 33 #include "Exception.h" 34 34 #include "Heap.h" 35 #include "Interpreter.h" 35 36 #include "JITInlines.h" 36 37 #include "JSArray.h" … … 84 85 Structure* structure = currentInstruction[3].u.objectAllocationProfile->structure(); 85 86 size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity()); 86 MarkedAllocator* allocator = &m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize);87 MarkedAllocator* allocator = m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize); 87 88 88 89 RegisterID resultReg = regT0; … … 91 92 92 93 move(TrustedImmPtr(allocator), allocatorReg); 94 if (allocator) 95 addSlowCase(Jump()); 93 96 JumpList slowCases; 94 emitAllocateJSObject(resultReg, allocator Reg, TrustedImmPtr(structure), TrustedImmPtr(0), scratchReg, slowCases);97 emitAllocateJSObject(resultReg, allocator, allocatorReg, TrustedImmPtr(structure), TrustedImmPtr(0), scratchReg, slowCases); 95 98 addSlowCase(slowCases); 96 99 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 99 102 void JIT::emitSlow_op_new_object(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 100 103 { 104 linkSlowCase(iter); 101 105 linkSlowCase(iter); 102 106 int dst = currentInstruction[1].u.operand; … … 773 777 774 778 JumpList slowCases; 775 emitAllocateJSObject(resultReg, allocatorReg, structureReg, TrustedImmPtr(0), scratchReg, slowCases);779 emitAllocateJSObject(resultReg, nullptr, allocatorReg, structureReg, TrustedImmPtr(0), scratchReg, slowCases); 776 780 addSlowCase(slowCases); 777 781 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 783 787 linkSlowCase(iter); // doesn't have rare data 784 788 linkSlowCase(iter); // doesn't have an allocation profile 785 linkSlowCase(iter); // allocation failed 789 linkSlowCase(iter); // allocation failed (no allocator) 790 linkSlowCase(iter); // allocation failed (allocator empty) 786 791 linkSlowCase(iter); // cached function didn't match 787 792 -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r204912 r205462 40 40 #include "LinkBuffer.h" 41 41 #include "MaxFrameExtentForSlowPathCall.h" 42 #include "Opcode.h" 42 43 #include "SlowPathCall.h" 43 44 #include "TypeProfilerLog.h" … … 164 165 Structure* structure = currentInstruction[3].u.objectAllocationProfile->structure(); 165 166 size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity()); 166 MarkedAllocator* allocator = &m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize);167 MarkedAllocator* allocator = m_vm->heap.allocatorForObjectWithoutDestructor(allocationSize); 167 168 168 169 RegisterID resultReg = returnValueGPR; … … 171 172 172 173 move(TrustedImmPtr(allocator), allocatorReg); 174 if (allocator) 175 addSlowCase(Jump()); 173 176 JumpList slowCases; 174 emitAllocateJSObject(resultReg, allocator Reg, TrustedImmPtr(structure), TrustedImmPtr(0), scratchReg, slowCases);177 emitAllocateJSObject(resultReg, allocator, allocatorReg, TrustedImmPtr(structure), TrustedImmPtr(0), scratchReg, slowCases); 175 178 addSlowCase(slowCases); 176 179 emitStoreCell(currentInstruction[1].u.operand, resultReg); … … 179 182 void JIT::emitSlow_op_new_object(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 180 183 { 184 linkSlowCase(iter); 181 185 linkSlowCase(iter); 182 186 int dst = currentInstruction[1].u.operand; … … 1033 1037 1034 1038 JumpList slowCases; 1035 emitAllocateJSObject(resultReg, allocatorReg, structureReg, TrustedImmPtr(0), scratchReg, slowCases);1039 emitAllocateJSObject(resultReg, nullptr, allocatorReg, structureReg, TrustedImmPtr(0), scratchReg, slowCases); 1036 1040 addSlowCase(slowCases); 1037 1041 emitStoreCell(currentInstruction[1].u.operand, resultReg); … … 1043 1047 linkSlowCase(iter); // doesn't have rare data 1044 1048 linkSlowCase(iter); // doesn't have an allocation profile 1045 linkSlowCase(iter); // allocation failed 1049 linkSlowCase(iter); // allocation failed (no allocator) 1050 linkSlowCase(iter); // allocation failed (allocator empty) 1046 1051 linkSlowCase(iter); // cached function didn't match 1047 1052 -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r205198 r205462 45 45 #include "HostCallReturnValue.h" 46 46 #include "ICStats.h" 47 #include "Interpreter.h" 47 48 #include "JIT.h" 48 49 #include "JITExceptions.h" … … 479 480 if (stubInfo->considerCaching(structure)) 480 481 repatchPutByID(exec, baseObject, structure, ident, slot, *stubInfo, Direct); 481 }482 483 void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)484 {485 VM& vm = exec->vm();486 NativeCallFrameTracer tracer(&vm, exec);487 488 ASSERT(structure->outOfLineCapacity() > base->structure(vm)->outOfLineCapacity());489 ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));490 base->setStructureAndReallocateStorageIfNecessary(vm, structure);491 base->putDirect(vm, offset, JSValue::decode(value));492 482 } 493 483 … … 2158 2148 2159 2149 ASSERT(!object->structure()->outOfLineCapacity()); 2160 DeferGC deferGC(vm.heap);2161 2150 Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity); 2162 2151 object->setButterflyWithoutChangingStructure(vm, result); … … 2169 2158 NativeCallFrameTracer tracer(&vm, exec); 2170 2159 2171 DeferGC deferGC(vm.heap);2172 2160 Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize); 2173 2161 object->setButterflyWithoutChangingStructure(vm, result); -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r204912 r205462 39 39 namespace JSC { 40 40 41 typedef int64_t EncodedJSValue; 42 41 43 class ArrayAllocationProfile; 42 44 class ArrayProfile; 45 class Butterfly; 43 46 class CallLinkInfo; 44 47 class CodeBlock; … … 46 49 class JITAddGenerator; 47 50 class JSArray; 51 class JSCell; 48 52 class JSFunction; 53 class JSGlobalObject; 49 54 class JSLexicalEnvironment; 55 class JSObject; 50 56 class JSScope; 57 class JSString; 58 class JSValue; 51 59 class RegExpObject; 52 60 class Register; 61 class Structure; 53 62 class StructureStubInfo; 54 63 class SymbolTable; … … 57 66 struct ByValInfo; 58 67 struct InlineCallFrame; 68 struct Instruction; 59 69 struct ArithProfile; 60 70 … … 73 83 Ap: ArrayProfile* 74 84 Arp: ArithProfile* 85 B: Butterfly* 75 86 By: ByValInfo* 76 87 C: JSCell* … … 280 291 typedef char* (JIT_OPERATION *P_JITOperation_EStSS)(ExecState*, Structure*, size_t, size_t); 281 292 typedef char* (JIT_OPERATION *P_JITOperation_EStZ)(ExecState*, Structure*, int32_t); 293 typedef char* (JIT_OPERATION *P_JITOperation_EStZB)(ExecState*, Structure*, int32_t, Butterfly*); 282 294 typedef char* (JIT_OPERATION *P_JITOperation_EZZ)(ExecState*, int32_t, int32_t); 283 295 typedef SlowPathReturnType (JIT_OPERATION *Sprt_JITOperation_ECli)(ExecState*, CallLinkInfo*); … … 321 333 void JIT_OPERATION operationPutByIdDirectStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL; 322 334 void JIT_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState*, StructureStubInfo*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, UniquedStringImpl*) WTF_INTERNAL; 323 void JIT_OPERATION operationReallocateStorageAndFinishPut(ExecState*, JSObject*, Structure*, PropertyOffset, EncodedJSValue) WTF_INTERNAL;324 335 void JIT_OPERATION operationPutByValOptimize(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ByValInfo*) WTF_INTERNAL; 325 336 void JIT_OPERATION operationDirectPutByValOptimize(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, ByValInfo*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r204992 r205462 1247 1247 void JIT::emitWriteBarrier(JSCell* owner) 1248 1248 { 1249 if (! MarkedBlock::blockFor(owner)->isMarked(owner)) {1249 if (!owner->cellContainer().isMarked(owner)) { 1250 1250 Jump ownerIsRememberedOrInEden = jumpIfIsRememberedOrInEden(owner); 1251 1251 callOperation(operationUnconditionalWriteBarrier, owner); -
trunk/Source/JavaScriptCore/jit/JITThunks.cpp
r204912 r205462 31 31 #include "Executable.h" 32 32 #include "JIT.h" 33 #include "JSCInlines.h" 34 #include "LLIntData.h" 33 35 #include "VM.h" 34 #include "JSCInlines.h"35 36 36 37 namespace JSC { -
trunk/Source/JavaScriptCore/jit/JITThunks.h
r204912 r205462 31 31 #include "CallData.h" 32 32 #include "Intrinsic.h" 33 #include "LowLevelInterpreter.h"34 33 #include "MacroAssemblerCodeRef.h" 35 34 #include "ThunkGenerator.h" -
trunk/Source/JavaScriptCore/jsc.cpp
r205387 r205462 637 637 static EncodedJSValue JSC_HOST_CALL functionPlatformSupportsSamplingProfiler(ExecState*); 638 638 static EncodedJSValue JSC_HOST_CALL functionGenerateHeapSnapshot(ExecState*); 639 static EncodedJSValue JSC_HOST_CALL functionResetSuperSamplerState(ExecState*); 640 static EncodedJSValue JSC_HOST_CALL functionEnsureArrayStorage(ExecState*); 639 641 #if ENABLE(SAMPLING_PROFILER) 640 642 static EncodedJSValue JSC_HOST_CALL functionStartSamplingProfiler(ExecState*); … … 873 875 addFunction(vm, "platformSupportsSamplingProfiler", functionPlatformSupportsSamplingProfiler, 0); 874 876 addFunction(vm, "generateHeapSnapshot", functionGenerateHeapSnapshot, 0); 877 addFunction(vm, "resetSuperSamplerState", functionResetSuperSamplerState, 0); 878 addFunction(vm, "ensureArrayStorage", functionEnsureArrayStorage, 0); 875 879 #if ENABLE(SAMPLING_PROFILER) 876 880 addFunction(vm, "startSamplingProfiler", functionStartSamplingProfiler, 0); … … 1214 1218 if (!object) 1215 1219 return JSValue::encode(jsNontrivialString(exec, ASCIILiteral("<not object>"))); 1216 return JSValue::encode(jsNontrivialString(exec, toString("< Public length: ", object->getArrayLength(), "; vector length: ", object->getVectorLength(), ">")));1220 return JSValue::encode(jsNontrivialString(exec, toString("<Butterfly: ", RawPointer(object->butterfly()), "; public length: ", object->getArrayLength(), "; vector length: ", object->getVectorLength(), ">"))); 1217 1221 } 1218 1222 … … 1961 1965 } 1962 1966 1967 EncodedJSValue JSC_HOST_CALL functionResetSuperSamplerState(ExecState*) 1968 { 1969 resetSuperSamplerState(); 1970 return JSValue::encode(jsUndefined()); 1971 } 1972 1973 EncodedJSValue JSC_HOST_CALL functionEnsureArrayStorage(ExecState* exec) 1974 { 1975 for (unsigned i = 0; i < exec->argumentCount(); ++i) { 1976 if (JSObject* object = jsDynamicCast<JSObject*>(exec->argument(0))) 1977 object->ensureArrayStorage(exec->vm()); 1978 } 1979 return JSValue::encode(jsUndefined()); 1980 } 1981 1963 1982 #if ENABLE(SAMPLING_PROFILER) 1964 1983 EncodedJSValue JSC_HOST_CALL functionStartSamplingProfiler(ExecState* exec) … … 2072 2091 res = jscmain(argc, argv); 2073 2092 EXCEPT(res = 3) 2074 if (Options::logHeapStatisticsAtExit()) 2075 HeapStatistics::reportSuccess(); 2076 if (Options::reportLLIntStats()) 2077 LLInt::Data::finalizeStats(); 2093 finalizeStatsAtEndOfTesting(); 2078 2094 2079 2095 #if PLATFORM(EFL) -
trunk/Source/JavaScriptCore/llint/LLIntData.cpp
r204912 r205462 212 212 STATIC_ASSERT(GetPutInfo::initializationBits == 0xffc00); 213 213 214 STATIC_ASSERT(MarkedBlock::block Mask == ~static_cast<decltype(MarkedBlock::blockMask)>(0x3fff));214 STATIC_ASSERT(MarkedBlock::blockSize == 16 * 1024); 215 215 216 216 ASSERT(bitwise_cast<uintptr_t>(ShadowChicken::Packet::tailMarker()) == static_cast<uintptr_t>(0x7a11)); -
trunk/Source/JavaScriptCore/llint/LLIntExceptions.cpp
r204912 r205462 30 30 #include "Instruction.h" 31 31 #include "LLIntCommon.h" 32 #include "LLIntData.h" 32 33 #include "LowLevelInterpreter.h" 33 34 #include "JSCInlines.h" -
trunk/Source/JavaScriptCore/llint/LLIntThunks.cpp
r205330 r205462 34 34 #include "JSObject.h" 35 35 #include "LLIntCLoop.h" 36 #include "LLIntData.h" 36 37 #include "LinkBuffer.h" 37 38 #include "LowLevelInterpreter.h" -
trunk/Source/JavaScriptCore/llint/LLIntThunks.h
r205330 r205462 33 33 class VM; 34 34 struct ProtoCallFrame; 35 typedef int64_t EncodedJSValue; 35 36 36 37 extern "C" { -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r205321 r205462 1069 1069 end 1070 1070 1071 macro allocateJSObject(allocator, structure, result, scratch1, slowCase)1072 const offsetOfFirstFreeCell =1073 MarkedAllocator::m_freeList +1074 MarkedBlock::FreeList::head1075 1076 # Get the object from the free list.1077 loadp offsetOfFirstFreeCell[allocator], result1078 btpz result, slowCase1079 1080 # Remove the object from the free list.1081 loadp [result], scratch11082 storep scratch1, offsetOfFirstFreeCell[allocator]1083 1084 # Initialize the object.1085 storep 0, JSObject::m_butterfly[result]1086 storeStructureWithTypeInfo(result, structure, scratch1)1087 end1088 1089 1071 macro doReturn() 1090 1072 restoreCalleeSavesUsedByLLInt() … … 1306 1288 callOpcodeSlowPath(_slow_path_create_cloned_arguments) 1307 1289 dispatch(2) 1290 1291 1292 _llint_op_create_this: 1293 traceExecution() 1294 callOpcodeSlowPath(_slow_path_create_this) 1295 dispatch(5) 1296 1297 1298 _llint_op_new_object: 1299 traceExecution() 1300 callOpcodeSlowPath(_llint_slow_path_new_object) 1301 dispatch(4) 1308 1302 1309 1303 -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
r204912 r205462 26 26 #include "config.h" 27 27 #include "LowLevelInterpreter.h" 28 28 29 #include "LLIntOfflineAsmConfig.h" 29 30 #include <wtf/InlineASM.h> 30 31 31 32 #if !ENABLE(JIT) 33 #include "CLoopStackInlines.h" 32 34 #include "CodeBlock.h" 33 35 #include "CommonSlowPaths.h" 36 #include "Interpreter.h" 34 37 #include "LLIntCLoop.h" 38 #include "LLIntData.h" 35 39 #include "LLIntSlowPaths.h" 36 40 #include "JSCInlines.h" -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
r204912 r205462 306 306 loadp Callee + PayloadOffset[cfr], t3 307 307 andp MarkedBlockMask, t3 308 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t3308 loadp MarkedBlock::m_vm[t3], t3 309 309 restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0) 310 310 loadp VM::callFrameForCatch[t3], cfr … … 654 654 loadp Callee + PayloadOffset[cfr], t3 655 655 andp MarkedBlockMask, t3 656 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t3656 loadp MarkedBlock::m_vm[t3], t3 657 657 btiz VM::m_exception[t3], .noException 658 658 jmp label … … 703 703 704 704 705 _llint_op_create_this:706 traceExecution()707 loadi 8[PC], t0708 loadp PayloadOffset[cfr, t0, 8], t0709 bbneq JSCell::m_type[t0], JSFunctionType, .opCreateThisSlow710 loadp JSFunction::m_rareData[t0], t5711 btpz t5, .opCreateThisSlow712 loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_allocator[t5], t1713 loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_structure[t5], t2714 btpz t1, .opCreateThisSlow715 loadpFromInstruction(4, t5)716 bpeq t5, 1, .hasSeenMultipleCallee717 bpneq t5, t0, .opCreateThisSlow718 .hasSeenMultipleCallee:719 allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)720 loadi 4[PC], t1721 storei CellTag, TagOffset[cfr, t1, 8]722 storei t0, PayloadOffset[cfr, t1, 8]723 dispatch(5)724 725 .opCreateThisSlow:726 callOpcodeSlowPath(_slow_path_create_this)727 dispatch(5)728 729 730 705 _llint_op_to_this: 731 706 traceExecution() … … 740 715 .opToThisSlow: 741 716 callOpcodeSlowPath(_slow_path_to_this) 742 dispatch(4)743 744 745 _llint_op_new_object:746 traceExecution()747 loadpFromInstruction(3, t0)748 loadp ObjectAllocationProfile::m_allocator[t0], t1749 loadp ObjectAllocationProfile::m_structure[t0], t2750 allocateJSObject(t1, t2, t0, t3, .opNewObjectSlow)751 loadi 4[PC], t1752 storei CellTag, TagOffset[cfr, t1, 8]753 storei t0, PayloadOffset[cfr, t1, 8]754 dispatch(4)755 756 .opNewObjectSlow:757 callOpcodeSlowPath(_llint_slow_path_new_object)758 717 dispatch(4) 759 718 … … 1998 1957 loadp Callee + PayloadOffset[cfr], t3 1999 1958 andp MarkedBlockMask, t3 2000 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t31959 loadp MarkedBlock::m_vm[t3], t3 2001 1960 restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0) 2002 1961 loadp VM::callFrameForCatch[t3], cfr … … 2013 1972 loadp Callee + PayloadOffset[cfr], t3 2014 1973 andp MarkedBlockMask, t3 2015 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t31974 loadp MarkedBlock::m_vm[t3], t3 2016 1975 2017 1976 loadi VM::m_exception[t3], t0 … … 2048 2007 loadp Callee[cfr], t1 2049 2008 andp MarkedBlockMask, t1 2050 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t1], t12009 loadp MarkedBlock::m_vm[t1], t1 2051 2010 copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(t1, t2) 2052 2011 jmp VM::targetMachinePCForThrow[t1] … … 2067 2026 subp 8, sp # align stack pointer 2068 2027 andp MarkedBlockMask, t1 2069 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t1], t32028 loadp MarkedBlock::m_vm[t1], t3 2070 2029 storep cfr, VM::topCallFrame[t3] 2071 2030 move cfr, a0 # a0 = ecx … … 2077 2036 loadp Callee + PayloadOffset[cfr], t3 2078 2037 andp MarkedBlockMask, t3 2079 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t32038 loadp MarkedBlock::m_vm[t3], t3 2080 2039 addp 8, sp 2081 2040 elsif ARM or ARMv7 or ARMv7_TRADITIONAL or C_LOOP or MIPS or SH4 … … 2083 2042 # t1 already contains the Callee. 2084 2043 andp MarkedBlockMask, t1 2085 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t1], t12044 loadp MarkedBlock::m_vm[t1], t1 2086 2045 storep cfr, VM::topCallFrame[t1] 2087 2046 move cfr, a0 … … 2096 2055 loadp Callee + PayloadOffset[cfr], t3 2097 2056 andp MarkedBlockMask, t3 2098 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t32057 loadp MarkedBlock::m_vm[t3], t3 2099 2058 addp 8, sp 2100 2059 else -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r204912 r205462 278 278 loadp Callee[cfr], t3 279 279 andp MarkedBlockMask, t3 280 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t3280 loadp MarkedBlock::m_vm[t3], t3 281 281 restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0) 282 282 loadp VM::callFrameForCatch[t3], cfr … … 560 560 loadp Callee[cfr], t3 561 561 andp MarkedBlockMask, t3 562 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t3562 loadp MarkedBlock::m_vm[t3], t3 563 563 btqz VM::m_exception[t3], .noException 564 564 jmp label … … 608 608 609 609 610 _llint_op_create_this:611 traceExecution()612 loadisFromInstruction(2, t0)613 loadp [cfr, t0, 8], t0614 bbneq JSCell::m_type[t0], JSFunctionType, .opCreateThisSlow615 loadp JSFunction::m_rareData[t0], t3616 btpz t3, .opCreateThisSlow617 loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_allocator[t3], t1618 loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_structure[t3], t2619 btpz t1, .opCreateThisSlow620 loadpFromInstruction(4, t3)621 bpeq t3, 1, .hasSeenMultipleCallee622 bpneq t3, t0, .opCreateThisSlow623 .hasSeenMultipleCallee:624 allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)625 loadisFromInstruction(1, t1)626 storeq t0, [cfr, t1, 8]627 dispatch(5)628 629 .opCreateThisSlow:630 callOpcodeSlowPath(_slow_path_create_this)631 dispatch(5)632 633 634 610 _llint_op_to_this: 635 611 traceExecution() … … 645 621 .opToThisSlow: 646 622 callOpcodeSlowPath(_slow_path_to_this) 647 dispatch(4)648 649 650 _llint_op_new_object:651 traceExecution()652 loadpFromInstruction(3, t0)653 loadp ObjectAllocationProfile::m_allocator[t0], t1654 loadp ObjectAllocationProfile::m_structure[t0], t2655 allocateJSObject(t1, t2, t0, t3, .opNewObjectSlow)656 loadisFromInstruction(1, t1)657 storeq t0, [cfr, t1, 8]658 dispatch(4)659 660 .opNewObjectSlow:661 callOpcodeSlowPath(_llint_slow_path_new_object)662 623 dispatch(4) 663 624 … … 1959 1920 loadp Callee[cfr], t3 1960 1921 andp MarkedBlockMask, t3 1961 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t31922 loadp MarkedBlock::m_vm[t3], t3 1962 1923 restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0) 1963 1924 loadp VM::callFrameForCatch[t3], cfr … … 1978 1939 loadp Callee[cfr], t3 1979 1940 andp MarkedBlockMask, t3 1980 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t31941 loadp MarkedBlock::m_vm[t3], t3 1981 1942 1982 1943 loadq VM::m_exception[t3], t0 … … 2005 1966 loadp Callee[cfr], t1 2006 1967 andp MarkedBlockMask, t1 2007 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t1], t11968 loadp MarkedBlock::m_vm[t1], t1 2008 1969 copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(t1, t2) 2009 1970 … … 2015 1976 loadp Callee[cfr], t1 2016 1977 andp MarkedBlockMask, t1 2017 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t1], t11978 loadp MarkedBlock::m_vm[t1], t1 2018 1979 jmp VM::targetMachinePCForThrow[t1] 2019 1980 … … 2030 1991 loadp Callee[cfr], t0 2031 1992 andp MarkedBlockMask, t0, t1 2032 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t1], t11993 loadp MarkedBlock::m_vm[t1], t1 2033 1994 storep cfr, VM::topCallFrame[t1] 2034 1995 if ARM64 or C_LOOP … … 2052 2013 loadp Callee[cfr], t3 2053 2014 andp MarkedBlockMask, t3 2054 loadp MarkedBlock::m_ weakSet + WeakSet::m_vm[t3], t32015 loadp MarkedBlock::m_vm[t3], t3 2055 2016 2056 2017 functionEpilogue() -
trunk/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "ModuleAnalyzer.h" 28 28 29 #include "IdentifierInlines.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 29 #include "JSCInlines.h" 32 30 #include "JSGlobalObject.h" 33 31 #include "JSModuleRecord.h" -
trunk/Source/JavaScriptCore/parser/NodeConstructors.h
r204912 r205462 24 24 #include "Nodes.h" 25 25 #include "Lexer.h" 26 #include "Opcode.h" 26 27 #include "Parser.h" 27 28 -
trunk/Source/JavaScriptCore/parser/Nodes.h
r204912 r205462 30 30 #include "Error.h" 31 31 #include "JITCode.h" 32 #include "Opcode.h"33 32 #include "ParserArena.h" 34 33 #include "ParserTokens.h" … … 41 40 42 41 namespace JSC { 42 43 enum OpcodeID : unsigned; 43 44 44 45 class ArgumentListNode; -
trunk/Source/JavaScriptCore/profiler/ProfilerBytecode.cpp
r204912 r205462 29 29 #include "JSGlobalObject.h" 30 30 #include "ObjectConstructor.h" 31 #include "Opcode.h" 31 32 #include "JSCInlines.h" 32 33 -
trunk/Source/JavaScriptCore/profiler/ProfilerBytecode.h
r204912 r205462 28 28 29 29 #include "JSCJSValue.h" 30 #include "Opcode.h"31 30 #include <wtf/text/CString.h> 32 31 33 namespace JSC { namespace Profiler { 32 namespace JSC { 33 34 enum OpcodeID : unsigned; 35 36 namespace Profiler { 34 37 35 38 class Bytecode { -
trunk/Source/JavaScriptCore/profiler/ProfilerBytecodeSequence.cpp
r204912 r205462 28 28 29 29 #include "CodeBlock.h" 30 #include "Interpreter.h" 31 #include "JSCInlines.h" 30 32 #include "JSGlobalObject.h" 31 33 #include "Operands.h" 32 #include "JSCInlines.h"33 34 #include <wtf/StringPrintStream.h> 34 35 -
trunk/Source/JavaScriptCore/runtime/ArrayConventions.h
r204912 r205462 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.3 * Copyright (C) 2003, 2007, 2008, 2009, 2012, 2016 Apple Inc. All rights reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 71 71 #define MAX_ARRAY_INDEX 0xFFFFFFFEU 72 72 73 // The value BASE_ VECTOR_LEN is the maximum number of vector elements we'll allocate73 // The value BASE_XXX_VECTOR_LEN is the maximum number of vector elements we'll allocate 74 74 // for an array that was created with a sepcified length (e.g. a = new Array(123)) 75 #define BASE_VECTOR_LEN 4U 76 75 #define BASE_CONTIGUOUS_VECTOR_LEN 3U 76 #define BASE_CONTIGUOUS_VECTOR_LEN_EMPTY 5U 77 #define BASE_ARRAY_STORAGE_VECTOR_LEN 4U 78 77 79 // The upper bound to the size we'll grow a zero length array when the first element 78 80 // is added. 79 #define FIRST_ VECTOR_GROW 4U81 #define FIRST_ARRAY_STORAGE_VECTOR_GROW 4U 80 82 81 83 #define MIN_BEYOND_LENGTH_SPARSE_INDEX 1000 … … 97 99 } 98 100 99 inline IndexingHeader indexingHeaderForArray (unsigned length, unsigned vectorLength)101 inline IndexingHeader indexingHeaderForArrayStorage(unsigned length, unsigned vectorLength) 100 102 { 101 103 IndexingHeader result; … … 105 107 } 106 108 107 inline IndexingHeader baseIndexingHeaderForArray (unsigned length)109 inline IndexingHeader baseIndexingHeaderForArrayStorage(unsigned length) 108 110 { 109 return indexingHeaderForArray(length, BASE_VECTOR_LEN); 111 return indexingHeaderForArrayStorage(length, BASE_ARRAY_STORAGE_VECTOR_LEN); 112 } 113 114 #if USE(JSVALUE64) 115 JS_EXPORT_PRIVATE void clearArrayMemset(WriteBarrier<Unknown>* base, unsigned count); 116 JS_EXPORT_PRIVATE void clearArrayMemset(double* base, unsigned count); 117 #endif // USE(JSVALUE64) 118 119 ALWAYS_INLINE void clearArray(WriteBarrier<Unknown>* base, unsigned count) 120 { 121 #if USE(JSVALUE64) 122 const unsigned minCountForMemset = 100; 123 if (count >= minCountForMemset) { 124 clearArrayMemset(base, count); 125 return; 126 } 127 #endif 128 129 for (unsigned i = count; i--;) 130 base[i].clear(); 131 } 132 133 ALWAYS_INLINE void clearArray(double* base, unsigned count) 134 { 135 #if USE(JSVALUE64) 136 const unsigned minCountForMemset = 100; 137 if (count >= minCountForMemset) { 138 clearArrayMemset(base, count); 139 return; 140 } 141 #endif 142 143 for (unsigned i = count; i--;) 144 base[i] = PNaN; 110 145 } 111 146 -
trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
r205198 r205462 1007 1007 return JSValue::encode(jsUndefined()); 1008 1008 } 1009 1009 1010 1010 setLength(exec, thisObj, length - deleteCount + additionalArgs); 1011 1011 return JSValue::encode(result); … … 1144 1144 1145 1145 IndexingType type = first->mergeIndexingTypeForCopying(indexingTypeForValue(second) | IsArray); 1146 1146 1147 if (type == NonArray) 1147 1148 type = first->indexingType(); … … 1172 1173 1173 1174 JSArray* firstArray = jsCast<JSArray*>(exec->uncheckedArgument(0)); 1174 1175 1175 1176 // This code assumes that neither array has set Symbol.isConcatSpreadable. If the first array 1176 1177 // has indexed accessors then one of those accessors might change the value of Symbol.isConcatSpreadable … … 1188 1189 1189 1190 JSArray* secondArray = jsCast<JSArray*>(second); 1190 1191 1191 1192 Butterfly* firstButterfly = firstArray->butterfly(); 1192 1193 Butterfly* secondButterfly = secondArray->butterfly(); … … 1195 1196 unsigned secondArraySize = secondButterfly->publicLength(); 1196 1197 1197 IndexingType type = firstArray->mergeIndexingTypeForCopying(secondArray->indexingType()); 1198 IndexingType secondType = secondArray->indexingType(); 1199 IndexingType type = firstArray->mergeIndexingTypeForCopying(secondType); 1198 1200 if (type == NonArray || !firstArray->canFastCopy(vm, secondArray) || firstArraySize + secondArraySize >= MIN_SPARSE_ARRAY_INDEX) { 1199 1201 JSArray* result = constructEmptyArray(exec, nullptr, firstArraySize + secondArraySize); … … 1214 1216 if (!result) 1215 1217 return JSValue::encode(throwOutOfMemoryError(exec, scope)); 1216 1218 1217 1219 if (type == ArrayWithDouble) { 1218 1220 double* buffer = result->butterfly()->contiguousDouble().data(); … … 1222 1224 WriteBarrier<Unknown>* buffer = result->butterfly()->contiguous().data(); 1223 1225 memcpy(buffer, firstButterfly->contiguous().data(), sizeof(JSValue) * firstArraySize); 1224 memcpy(buffer + firstArraySize, secondButterfly->contiguous().data(), sizeof(JSValue) * secondArraySize); 1226 if (secondType != ArrayWithUndecided) 1227 memcpy(buffer + firstArraySize, secondButterfly->contiguous().data(), sizeof(JSValue) * secondArraySize); 1228 else { 1229 for (unsigned i = secondArraySize; i--;) 1230 buffer[i + firstArraySize].clear(); 1231 } 1225 1232 } 1226 1233 -
trunk/Source/JavaScriptCore/runtime/ArrayStorage.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 #include "Butterfly.h" 31 31 #include "IndexingHeader.h" 32 #include "MarkedSpace.h" 32 33 #include "SparseArrayValueMap.h" 34 #include "Structure.h" 33 35 #include "WriteBarrier.h" 34 36 #include <wtf/Noncopyable.h> … … 59 61 unsigned length() const { return indexingHeader()->publicLength(); } 60 62 void setLength(unsigned length) { indexingHeader()->setPublicLength(length); } 61 unsigned vectorLength() { return indexingHeader()->vectorLength(); }63 unsigned vectorLength() const { return indexingHeader()->vectorLength(); } 62 64 void setVectorLength(unsigned length) { indexingHeader()->setVectorLength(length); } 63 65 … … 100 102 return ArrayStorage::vectorOffset() + vectorLength * sizeof(WriteBarrier<Unknown>); 101 103 } 104 105 static size_t totalSizeFor(unsigned indexBias, size_t propertyCapacity, unsigned vectorLength) 106 { 107 return Butterfly::totalSize(indexBias, propertyCapacity, true, sizeFor(vectorLength)); 108 } 109 110 size_t totalSize(size_t propertyCapacity) const 111 { 112 return totalSizeFor(m_indexBias, propertyCapacity, vectorLength()); 113 } 114 115 size_t totalSize(Structure* structure) const 116 { 117 return totalSize(structure->outOfLineCapacity()); 118 } 119 120 static unsigned availableVectorLength(unsigned indexBias, size_t propertyCapacity, unsigned vectorLength) 121 { 122 size_t cellSize = MarkedSpace::optimalSizeFor(totalSizeFor(indexBias, propertyCapacity, vectorLength)); 123 124 vectorLength = (cellSize - totalSizeFor(indexBias, propertyCapacity, 0)) / sizeof(WriteBarrier<Unknown>); 125 126 return vectorLength; 127 } 128 129 static unsigned availableVectorLength(unsigned indexBias, Structure* structure, unsigned vectorLength) 130 { 131 return availableVectorLength(indexBias, structure->outOfLineCapacity(), vectorLength); 132 } 133 134 unsigned availableVectorLength(size_t propertyCapacity, unsigned vectorLength) 135 { 136 return availableVectorLength(m_indexBias, propertyCapacity, vectorLength); 137 } 138 139 unsigned availableVectorLength(Structure* structure, unsigned vectorLength) 140 { 141 return availableVectorLength(structure->outOfLineCapacity(), vectorLength); 142 } 143 144 static unsigned optimalVectorLength(unsigned indexBias, size_t propertyCapacity, unsigned vectorLength) 145 { 146 vectorLength = std::max(BASE_ARRAY_STORAGE_VECTOR_LEN, vectorLength); 147 return availableVectorLength(indexBias, propertyCapacity, vectorLength); 148 } 149 150 static unsigned optimalVectorLength(unsigned indexBias, Structure* structure, unsigned vectorLength) 151 { 152 return optimalVectorLength(indexBias, structure->outOfLineCapacity(), vectorLength); 153 } 154 155 unsigned optimalVectorLength(size_t propertyCapacity, unsigned vectorLength) 156 { 157 return optimalVectorLength(m_indexBias, propertyCapacity, vectorLength); 158 } 159 160 unsigned optimalVectorLength(Structure* structure, unsigned vectorLength) 161 { 162 return optimalVectorLength(structure->outOfLineCapacity(), vectorLength); 163 } 102 164 }; 103 165 -
trunk/Source/JavaScriptCore/runtime/Butterfly.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 91 91 } 92 92 93 ALWAYS_INLINE static unsigned availableContiguousVectorLength(size_t propertyCapacity, unsigned vectorLength); 94 static unsigned availableContiguousVectorLength(Structure*, unsigned vectorLength); 95 96 ALWAYS_INLINE static unsigned optimalContiguousVectorLength(size_t propertyCapacity, unsigned vectorLength); 97 static unsigned optimalContiguousVectorLength(Structure*, unsigned vectorLength); 98 93 99 // This method is here not just because it's handy, but to remind you that 94 100 // the whole point of butterflies is to do evil pointer arithmetic. -
trunk/Source/JavaScriptCore/runtime/ButterflyInlines.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 36 36 namespace JSC { 37 37 38 ALWAYS_INLINE unsigned Butterfly::availableContiguousVectorLength(size_t propertyCapacity, unsigned vectorLength) 39 { 40 size_t cellSize = totalSize(0, propertyCapacity, true, sizeof(EncodedJSValue) * vectorLength); 41 cellSize = MarkedSpace::optimalSizeFor(cellSize); 42 vectorLength = (cellSize - totalSize(0, propertyCapacity, true, 0)) / sizeof(EncodedJSValue); 43 return vectorLength; 44 } 45 46 ALWAYS_INLINE unsigned Butterfly::availableContiguousVectorLength(Structure* structure, unsigned vectorLength) 47 { 48 return availableContiguousVectorLength(structure ? structure->outOfLineCapacity() : 0, vectorLength); 49 } 50 51 ALWAYS_INLINE unsigned Butterfly::optimalContiguousVectorLength(size_t propertyCapacity, unsigned vectorLength) 52 { 53 if (!vectorLength) 54 vectorLength = BASE_CONTIGUOUS_VECTOR_LEN_EMPTY; 55 else 56 vectorLength = std::max(BASE_CONTIGUOUS_VECTOR_LEN, vectorLength); 57 return availableContiguousVectorLength(propertyCapacity, vectorLength); 58 } 59 60 ALWAYS_INLINE unsigned Butterfly::optimalContiguousVectorLength(Structure* structure, unsigned vectorLength) 61 { 62 return optimalContiguousVectorLength(structure ? structure->outOfLineCapacity() : 0, vectorLength); 63 } 64 38 65 inline Butterfly* Butterfly::createUninitialized(VM& vm, JSCell* intendedOwner, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) 39 66 { 40 void* temp;41 67 size_t size = totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); 42 RELEASE_ASSERT(vm.heap.tryAllocateStorage(intendedOwner, size, &temp));43 Butterfly* result = fromBase( temp, preCapacity, propertyCapacity);68 void* base = vm.heap.allocateAuxiliary(intendedOwner, size); 69 Butterfly* result = fromBase(base, preCapacity, propertyCapacity); 44 70 return result; 45 71 } … … 120 146 size_t oldSize = totalSize(0, propertyCapacity, hadIndexingHeader, oldIndexingPayloadSizeInBytes); 121 147 size_t newSize = totalSize(0, propertyCapacity, true, newIndexingPayloadSizeInBytes); 122 if (!vm.heap.tryReallocateStorage(intendedOwner, &theBase, oldSize, newSize)) 148 theBase = vm.heap.tryReallocateAuxiliary(intendedOwner, theBase, oldSize, newSize); 149 if (!theBase) 123 150 return 0; 124 151 return fromBase(theBase, 0, propertyCapacity); -
trunk/Source/JavaScriptCore/runtime/ClonedArguments.cpp
r204912 r205462 45 45 VM& vm, Structure* structure, JSFunction* callee, unsigned length) 46 46 { 47 unsigned vectorLength = std::max(BASE_VECTOR_LEN, length);47 unsigned vectorLength = length; 48 48 if (vectorLength > MAX_STORAGE_VECTOR_LENGTH) 49 49 return 0; 50 50 51 void* temp ;52 if (! vm.heap.tryAllocateStorage(0, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)), &temp))51 void* temp = vm.heap.tryAllocateAuxiliary(nullptr, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue))); 52 if (!temp) 53 53 return 0; 54 54 Butterfly* butterfly = Butterfly::fromBase(temp, 0, structure->outOfLineCapacity()); 55 55 butterfly->setVectorLength(vectorLength); 56 56 butterfly->setPublicLength(length); 57 58 for (unsigned i = length; i < vectorLength; ++i) 59 butterfly->contiguous()[i].clear(); 57 60 58 61 ClonedArguments* result = -
trunk/Source/JavaScriptCore/runtime/CommonSlowPathsExceptions.cpp
r205198 r205462 29 29 #include "CallFrame.h" 30 30 #include "CodeBlock.h" 31 #include "Interpreter.h" 31 32 #include "JITExceptions.h" 32 33 #include "LLIntCommon.h" -
trunk/Source/JavaScriptCore/runtime/CommonSlowPathsExceptions.h
r204912 r205462 27 27 #define CommonSlowPathExceptions_h 28 28 29 #include "MacroAssemblerCodeRef.h"30 31 29 namespace JSC { 32 30 33 31 class ExecState; 32 class JSObject; 34 33 35 34 namespace CommonSlowPaths { -
trunk/Source/JavaScriptCore/runtime/DataView.cpp
r204912 r205462 27 27 #include "DataView.h" 28 28 29 #include "JSCInlines.h" 29 30 #include "JSDataView.h" 30 31 #include "JSGlobalObject.h" -
trunk/Source/JavaScriptCore/runtime/DirectArguments.h
r204912 r205462 27 27 #define DirectArguments_h 28 28 29 #include "CopyBarrier.h" 29 30 #include "DirectArgumentsOffset.h" 30 31 #include "GenericArguments.h" -
trunk/Source/JavaScriptCore/runtime/ECMAScriptSpecInternalFunctions.cpp
r204912 r205462 29 29 #include "CallFrame.h" 30 30 #include "ConstructData.h" 31 #include "JSC JSValueInlines.h"31 #include "JSCInlines.h" 32 32 #include "RegExpObject.h" 33 33 -
trunk/Source/JavaScriptCore/runtime/Error.cpp
r205198 r205462 29 29 #include "ExceptionHelpers.h" 30 30 #include "FunctionPrototype.h" 31 #include "Interpreter.h" 31 32 #include "JSArray.h" 32 33 #include "JSFunction.h" … … 34 35 #include "JSObject.h" 35 36 #include "JSString.h" 37 #include "JSCInlines.h" 36 38 #include "NativeErrorConstructor.h" 37 #include "JSCInlines.h"38 39 #include "SourceCode.h" 40 #include "StackFrame.h" 39 41 40 42 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/Error.h
r205198 r205462 26 26 #include "ErrorInstance.h" 27 27 #include "InternalFunction.h" 28 #include "Interpreter.h"29 28 #include "JSObject.h" 30 29 #include "ThrowScope.h" -
trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp
r204912 r205462 27 27 #include "JSCInlines.h" 28 28 #include "JSGlobalObjectFunctions.h" 29 #include <wtf/text/StringBuilder.h> 29 30 30 31 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/ErrorInstance.h
r204912 r205462 22 22 #define ErrorInstance_h 23 23 24 #include " Interpreter.h"24 #include "JSObject.h" 25 25 #include "RuntimeType.h" 26 26 #include "SourceProvider.h" -
trunk/Source/JavaScriptCore/runtime/Exception.cpp
r204912 r205462 27 27 #include "Exception.h" 28 28 29 #include "Interpreter.h" 29 30 #include "JSCInlines.h" 30 31 -
trunk/Source/JavaScriptCore/runtime/Exception.h
r204912 r205462 27 27 #define Exception_h 28 28 29 #include "Interpreter.h" 29 #include "JSObject.h" 30 #include "StackFrame.h" 30 31 #include <wtf/Vector.h> 31 32 -
trunk/Source/JavaScriptCore/runtime/GeneratorPrototype.cpp
r204912 r205462 28 28 29 29 #include "JSCBuiltins.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 32 31 #include "JSGlobalObject.h" 33 #include "StructureInlines.h"34 32 35 33 #include "GeneratorPrototype.lut.h" -
trunk/Source/JavaScriptCore/runtime/InternalFunction.cpp
r204912 r205462 38 38 : JSDestructibleObject(vm, structure) 39 39 { 40 // exec->vm() wants callees to not be large allocations. 41 RELEASE_ASSERT(!isLargeAllocation()); 40 42 } 41 43 -
trunk/Source/JavaScriptCore/runtime/IntlCollator.cpp
r205198 r205462 2 2 * Copyright (C) 2015 Andy VanWagoner (thetalecrafter@gmail.com) 3 3 * Copyright (C) 2015 Sukolsak Sakshuwong (sukolsak@gmail.com) 4 * Copyright (C) 2016 Apple Inc. All Rights Reserved. 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 34 35 #include "IntlObject.h" 35 36 #include "JSBoundFunction.h" 36 #include "JSCJSValueInlines.h" 37 #include "JSCellInlines.h" 37 #include "JSCInlines.h" 38 38 #include "ObjectConstructor.h" 39 39 #include "SlotVisitorInlines.h" -
trunk/Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp
r204912 r205462 34 34 #include "IntlCollatorPrototype.h" 35 35 #include "IntlObject.h" 36 #include "JSCJSValueInlines.h" 37 #include "JSCellInlines.h" 36 #include "JSCInlines.h" 38 37 #include "Lookup.h" 39 #include "SlotVisitorInlines.h"40 #include "StructureInlines.h"41 38 42 39 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IntlCollatorPrototype.cpp
r205198 r205462 33 33 #include "IntlCollator.h" 34 34 #include "JSBoundFunction.h" 35 #include "JSCJSValueInlines.h" 36 #include "JSCellInlines.h" 37 #include "JSObject.h" 38 #include "StructureInlines.h" 35 #include "JSCInlines.h" 39 36 40 37 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IntlDateTimeFormat.cpp
r205332 r205462 35 35 #include "IntlObject.h" 36 36 #include "JSBoundFunction.h" 37 #include "JSCellInlines.h"38 37 #include "JSCInlines.h" 39 38 #include "ObjectConstructor.h" … … 41 40 #include <unicode/udatpg.h> 42 41 #include <unicode/uenum.h> 42 #include <wtf/text/StringBuilder.h> 43 43 44 44 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp
r204912 r205462 34 34 #include "IntlObject.h" 35 35 #include "IntlObjectInlines.h" 36 #include "JSCJSValueInlines.h" 37 #include "JSCellInlines.h" 36 #include "JSCInlines.h" 38 37 #include "Lookup.h" 39 #include "SlotVisitorInlines.h"40 #include "StructureInlines.h"41 38 42 39 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IntlDateTimeFormatPrototype.cpp
r205324 r205462 36 36 #include "IntlObject.h" 37 37 #include "JSBoundFunction.h" 38 #include "JSCJSValueInlines.h" 39 #include "JSCellInlines.h" 38 #include "JSCInlines.h" 40 39 #include "JSObjectInlines.h" 41 #include "StructureInlines.h"42 40 43 41 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IntlNumberFormat.cpp
r205332 r205462 35 35 #include "IntlObject.h" 36 36 #include "JSBoundFunction.h" 37 #include "JSCellInlines.h"38 37 #include "JSCInlines.h" 39 38 #include "ObjectConstructor.h" -
trunk/Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp
r204912 r205462 34 34 #include "IntlObject.h" 35 35 #include "IntlObjectInlines.h" 36 #include "JSCJSValueInlines.h" 37 #include "JSCellInlines.h" 36 #include "JSCInlines.h" 38 37 #include "Lookup.h" 39 #include "SlotVisitorInlines.h"40 #include "StructureInlines.h"41 38 42 39 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IntlNumberFormatPrototype.cpp
r205324 r205462 34 34 #include "IntlNumberFormat.h" 35 35 #include "JSBoundFunction.h" 36 #include "JSCJSValueInlines.h" 37 #include "JSCellInlines.h" 36 #include "JSCInlines.h" 38 37 #include "JSObjectInlines.h" 39 #include "StructureInlines.h"40 38 41 39 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IntlObject.cpp
r205198 r205462 51 51 #include <wtf/NeverDestroyed.h> 52 52 #include <wtf/PlatformUserPreferredLanguages.h> 53 #include <wtf/text/StringBuilder.h> 53 54 54 55 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/IteratorPrototype.cpp
r204912 r205462 28 28 29 29 #include "JSCBuiltins.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 32 31 #include "JSGlobalObject.h" 33 32 #include "ObjectConstructor.h" 34 #include "StructureInlines.h"35 33 36 34 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSArray.cpp
r205324 r205462 61 61 } 62 62 63 JSArray* JSArray::tryCreateUninitialized(VM& vm, Structure* structure, unsigned initialLength) 64 { 65 if (initialLength > MAX_STORAGE_VECTOR_LENGTH) 66 return 0; 67 68 unsigned outOfLineStorage = structure->outOfLineCapacity(); 69 70 Butterfly* butterfly; 71 IndexingType indexingType = structure->indexingType(); 72 if (LIKELY(!hasAnyArrayStorage(indexingType))) { 73 ASSERT( 74 hasUndecided(indexingType) 75 || hasInt32(indexingType) 76 || hasDouble(indexingType) 77 || hasContiguous(indexingType)); 78 79 unsigned vectorLength = Butterfly::optimalContiguousVectorLength(structure, initialLength); 80 void* temp = vm.heap.tryAllocateAuxiliary(nullptr, Butterfly::totalSize(0, outOfLineStorage, true, vectorLength * sizeof(EncodedJSValue))); 81 if (!temp) 82 return nullptr; 83 butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage); 84 butterfly->setVectorLength(vectorLength); 85 butterfly->setPublicLength(initialLength); 86 if (hasDouble(indexingType)) { 87 for (unsigned i = initialLength; i < vectorLength; ++i) 88 butterfly->contiguousDouble()[i] = PNaN; 89 } else { 90 for (unsigned i = initialLength; i < vectorLength; ++i) 91 butterfly->contiguous()[i].clear(); 92 } 93 } else { 94 unsigned vectorLength = ArrayStorage::optimalVectorLength(0, structure, initialLength); 95 void* temp = vm.heap.tryAllocateAuxiliary(nullptr, Butterfly::totalSize(0, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength))); 96 if (!temp) 97 return nullptr; 98 butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage); 99 *butterfly->indexingHeader() = indexingHeaderForArrayStorage(initialLength, vectorLength); 100 ArrayStorage* storage = butterfly->arrayStorage(); 101 storage->m_indexBias = 0; 102 storage->m_sparseMap.clear(); 103 storage->m_numValuesInVector = initialLength; 104 for (unsigned i = initialLength; i < vectorLength; ++i) 105 storage->m_vector[i].clear(); 106 } 107 108 return createWithButterfly(vm, structure, butterfly); 109 } 110 63 111 void JSArray::setLengthWritable(ExecState* exec, bool writable) 64 112 { … … 244 292 245 293 // This method makes room in the vector, but leaves the new space for count slots uncleared. 246 bool JSArray::unshiftCountSlowCase(VM& vm, bool addToFront, unsigned count)294 bool JSArray::unshiftCountSlowCase(VM& vm, DeferGC&, bool addToFront, unsigned count) 247 295 { 248 296 ArrayStorage* storage = ensureArrayStorage(vm); 249 297 Butterfly* butterfly = storage->butterfly(); 250 unsigned propertyCapacity = structure(vm)->outOfLineCapacity(); 251 unsigned propertySize = structure(vm)->outOfLineSize(); 252 298 Structure* structure = this->structure(vm); 299 unsigned propertyCapacity = structure->outOfLineCapacity(); 300 unsigned propertySize = structure->outOfLineSize(); 301 253 302 // If not, we should have handled this on the fast path. 254 303 ASSERT(!addToFront || count > storage->m_indexBias); … … 262 311 263 312 unsigned length = storage->length(); 264 unsigned usedVectorLength = min(storage->vectorLength(), length); 313 unsigned oldVectorLength = storage->vectorLength(); 314 unsigned usedVectorLength = min(oldVectorLength, length); 265 315 ASSERT(usedVectorLength <= MAX_STORAGE_VECTOR_LENGTH); 266 316 // Check that required vector length is possible, in an overflow-safe fashion. … … 273 323 unsigned currentCapacity = storage->vectorLength() + storage->m_indexBias; 274 324 // The calculation of desiredCapacity won't overflow, due to the range of MAX_STORAGE_VECTOR_LENGTH. 275 unsigned desiredCapacity = min(MAX_STORAGE_VECTOR_LENGTH, max(BASE_VECTOR_LEN, requiredVectorLength) << 1); 325 // FIXME: This code should be fixed to avoid internal fragmentation. It's not super high 326 // priority since increaseVectorLength() will "fix" any mistakes we make, but it would be cool 327 // to get this right eventually. 328 unsigned desiredCapacity = min(MAX_STORAGE_VECTOR_LENGTH, max(BASE_ARRAY_STORAGE_VECTOR_LEN, requiredVectorLength) << 1); 276 329 277 330 // Step 2: 278 331 // We're either going to choose to allocate a new ArrayStorage, or we're going to reuse the existing one. 279 332 280 DeferGC deferGC(vm.heap);281 333 void* newAllocBase = 0; 282 334 unsigned newStorageCapacity; 335 bool allocatedNewStorage; 283 336 // If the current storage array is sufficiently large (but not too large!) then just keep using it. 284 337 if (currentCapacity > desiredCapacity && isDenseEnoughForVector(currentCapacity, requiredVectorLength)) { 285 newAllocBase = butterfly->base(structure (vm));338 newAllocBase = butterfly->base(structure); 286 339 newStorageCapacity = currentCapacity; 340 allocatedNewStorage = false; 287 341 } else { 288 342 size_t newSize = Butterfly::totalSize(0, propertyCapacity, true, ArrayStorage::sizeFor(desiredCapacity)); 289 if (!vm.heap.tryAllocateStorage(this, newSize, &newAllocBase)) 343 newAllocBase = vm.heap.tryAllocateAuxiliary(this, newSize); 344 if (!newAllocBase) 290 345 return false; 291 346 newStorageCapacity = desiredCapacity; 347 allocatedNewStorage = true; 292 348 } 293 349 … … 307 363 postCapacity = min((storage->vectorLength() - length) >> 1, newStorageCapacity - requiredVectorLength); 308 364 // If we're moving contents within the same allocation, the post-capacity is being reduced. 309 ASSERT(newAllocBase != butterfly->base(structure (vm)) || postCapacity < storage->vectorLength() - length);365 ASSERT(newAllocBase != butterfly->base(structure) || postCapacity < storage->vectorLength() - length); 310 366 } 311 367 … … 319 375 memmove(newButterfly->arrayStorage()->m_vector + count, storage->m_vector, sizeof(JSValue) * usedVectorLength); 320 376 memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0)); 321 } else if ((newAllocBase != butterfly->base(structure(vm))) || (newIndexBias != storage->m_indexBias)) { 377 378 if (allocatedNewStorage) { 379 // We will set the vectorLength to newVectorLength. We populated requiredVectorLength 380 // (usedVectorLength + count), which is less. Clear the difference. 381 for (unsigned i = requiredVectorLength; i < newVectorLength; ++i) 382 newButterfly->arrayStorage()->m_vector[i].clear(); 383 } 384 } else if ((newAllocBase != butterfly->base(structure)) || (newIndexBias != storage->m_indexBias)) { 322 385 memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0)); 323 386 memmove(newButterfly->arrayStorage()->m_vector, storage->m_vector, sizeof(JSValue) * usedVectorLength); 324 325 WriteBarrier<Unknown>* newVector = newButterfly->arrayStorage()->m_vector; 387 326 388 for (unsigned i = requiredVectorLength; i < newVectorLength; i++) 327 new Vector[i].clear();389 newButterfly->arrayStorage()->m_vector[i].clear(); 328 390 } 329 391 330 392 newButterfly->arrayStorage()->setVectorLength(newVectorLength); 331 393 newButterfly->arrayStorage()->m_indexBias = newIndexBias; 394 332 395 setButterflyWithoutChangingStructure(vm, newButterfly); 333 396 … … 338 401 { 339 402 unsigned length = storage->length(); 340 403 341 404 // If the length is read only then we enter sparse mode, so should enter the following 'if'. 342 405 ASSERT(isLengthWritable() || storage->m_sparseMap); … … 998 1061 unsigned vectorLength = storage->vectorLength(); 999 1062 1063 // Need to have GC deferred around the unshiftCountSlowCase(), since that leaves the butterfly in 1064 // a weird state: some parts of it will be left uninitialized, which we will fill in here. 1065 DeferGC deferGC(vm.heap); 1066 1000 1067 if (moveFront && storage->m_indexBias >= count) { 1001 1068 Butterfly* newButterfly = storage->butterfly()->unshift(structure(), count); … … 1006 1073 } else if (!moveFront && vectorLength - length >= count) 1007 1074 storage = storage->butterfly()->arrayStorage(); 1008 else if (unshiftCountSlowCase(vm, moveFront, count))1075 else if (unshiftCountSlowCase(vm, deferGC, moveFront, count)) 1009 1076 storage = arrayStorage(); 1010 1077 else { … … 1200 1267 1201 1268 Butterfly* butterfly = m_butterfly.get(); 1202 1203 1269 switch (indexingType()) { 1204 1270 case ArrayClass: -
trunk/Source/JavaScriptCore/runtime/JSArray.h
r205324 r205462 1 1 /* 2 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2007, 2008, 2009, 2012, 2015 Apple Inc. All rights reserved.3 * Copyright (C) 2003, 2007, 2008, 2009, 2012, 2015-2016 Apple Inc. All rights reserved. 4 4 * 5 5 * This library is free software; you can redistribute it and/or … … 61 61 // - null-check the result (indicating out of memory, or otherwise unable to allocate vector). 62 62 // - call 'initializeIndex' for all properties in sequence, for 0 <= i < initialLength. 63 static JSArray* tryCreateUninitialized(VM&, Structure*, unsigned initialLength);63 JS_EXPORT_PRIVATE static JSArray* tryCreateUninitialized(VM&, Structure*, unsigned initialLength); 64 64 65 65 JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool throwException); … … 169 169 bool unshiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count); 170 170 bool unshiftCountWithArrayStorage(ExecState*, unsigned startIndex, unsigned count, ArrayStorage*); 171 bool unshiftCountSlowCase(VM&, bool, unsigned);171 bool unshiftCountSlowCase(VM&, DeferGC&, bool, unsigned); 172 172 173 173 bool setLengthWithArrayStorage(ExecState*, unsigned newLength, bool throwException, ArrayStorage*); … … 178 178 { 179 179 IndexingHeader header; 180 vectorLength = std::max(length, BASE_VECTOR_LEN); 180 vectorLength = Butterfly::optimalContiguousVectorLength( 181 intendedOwner ? intendedOwner->structure(vm) : 0, length); 181 182 header.setVectorLength(vectorLength); 182 183 header.setPublicLength(length); … … 189 190 { 190 191 Butterfly* butterfly = Butterfly::create( 191 vm, intendedOwner, 0, 0, true, baseIndexingHeaderForArray (initialLength),192 ArrayStorage::sizeFor(BASE_ VECTOR_LEN));192 vm, intendedOwner, 0, 0, true, baseIndexingHeaderForArrayStorage(initialLength), 193 ArrayStorage::sizeFor(BASE_ARRAY_STORAGE_VECTOR_LEN)); 193 194 ArrayStorage* storage = butterfly->arrayStorage(); 195 storage->m_sparseMap.clear(); 194 196 storage->m_indexBias = 0; 195 storage->m_sparseMap.clear();196 197 storage->m_numValuesInVector = 0; 197 198 return butterfly; … … 212 213 unsigned vectorLength; 213 214 butterfly = createContiguousArrayButterfly(vm, 0, initialLength, vectorLength); 214 ASSERT(initialLength < MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH); 215 if (hasDouble(structure->indexingType())) { 216 for (unsigned i = 0; i < vectorLength; ++i) 217 butterfly->contiguousDouble()[i] = PNaN; 218 } 215 if (hasDouble(structure->indexingType())) 216 clearArray(butterfly->contiguousDouble().data(), vectorLength); 217 else 218 clearArray(butterfly->contiguous().data(), vectorLength); 219 219 } else { 220 220 ASSERT( … … 222 222 || structure->indexingType() == ArrayWithArrayStorage); 223 223 butterfly = createArrayButterfly(vm, 0, initialLength); 224 } 225 226 return createWithButterfly(vm, structure, butterfly); 227 } 228 229 inline JSArray* JSArray::tryCreateUninitialized(VM& vm, Structure* structure, unsigned initialLength) 230 { 231 unsigned vectorLength = std::max(BASE_VECTOR_LEN, initialLength); 232 if (vectorLength > MAX_STORAGE_VECTOR_LENGTH) 233 return 0; 234 235 unsigned outOfLineStorage = structure->outOfLineCapacity(); 236 237 Butterfly* butterfly; 238 if (LIKELY(!hasAnyArrayStorage(structure->indexingType()))) { 239 ASSERT( 240 hasUndecided(structure->indexingType()) 241 || hasInt32(structure->indexingType()) 242 || hasDouble(structure->indexingType()) 243 || hasContiguous(structure->indexingType())); 244 245 void* temp; 246 if (!vm.heap.tryAllocateStorage(0, Butterfly::totalSize(0, outOfLineStorage, true, vectorLength * sizeof(EncodedJSValue)), &temp)) 247 return 0; 248 butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage); 249 butterfly->setVectorLength(vectorLength); 250 butterfly->setPublicLength(initialLength); 251 if (hasDouble(structure->indexingType())) { 252 for (unsigned i = initialLength; i < vectorLength; ++i) 253 butterfly->contiguousDouble()[i] = PNaN; 254 } 255 } else { 256 void* temp; 257 if (!vm.heap.tryAllocateStorage(0, Butterfly::totalSize(0, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength)), &temp)) 258 return 0; 259 butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage); 260 *butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength); 261 ArrayStorage* storage = butterfly->arrayStorage(); 262 storage->m_indexBias = 0; 263 storage->m_sparseMap.clear(); 264 storage->m_numValuesInVector = initialLength; 224 for (unsigned i = 0; i < BASE_ARRAY_STORAGE_VECTOR_LEN; ++i) 225 butterfly->arrayStorage()->m_vector[i].clear(); 265 226 } 266 227 -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.h
r205131 r205462 27 27 #define JSArrayBufferView_h 28 28 29 #include "CopyBarrier.h" 29 30 #include "JSObject.h" 30 31 -
trunk/Source/JavaScriptCore/runtime/JSCInlines.h
r205198 r205462 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 42 42 #include "HeapInlines.h" 43 43 #include "IdentifierInlines.h" 44 #include "Interpreter.h"45 44 #include "JSArrayBufferViewInlines.h" 46 45 #include "JSCJSValueInlines.h" -
trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp
r205198 r205462 30 30 #include "ExceptionHelpers.h" 31 31 #include "GetterSetter.h" 32 #include "JSC JSValueInlines.h"32 #include "JSCInlines.h" 33 33 #include "JSFunction.h" 34 34 #include "JSGlobalObject.h" 35 35 #include "NumberObject.h" 36 #include "StructureInlines.h"37 36 #include <wtf/MathExtras.h> 38 37 #include <wtf/StringExtras.h> … … 279 278 else if (structure->classInfo()->isSubClassOf(Structure::info())) 280 279 out.print("Structure: ", inContext(*jsCast<Structure*>(asCell()), context)); 281 else { 280 else if (structure->classInfo()->isSubClassOf(JSObject::info())) { 281 out.print("Object: ", RawPointer(asCell())); 282 out.print(" with butterfly ", RawPointer(asObject(asCell())->butterfly())); 283 out.print(" (", inContext(*structure, context), ")"); 284 } else { 282 285 out.print("Cell: ", RawPointer(asCell())); 283 286 out.print(" (", inContext(*structure, context), ")"); -
trunk/Source/JavaScriptCore/runtime/JSCallee.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include "GetterSetter.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCell.h" 32 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 33 31 #include "JSGlobalObject.h" 34 #include "SlotVisitorInlines.h"35 32 #include "StackVisitor.h" 36 #include "StructureInlines.h"37 33 38 34 namespace JSC { … … 44 40 , m_scope(vm, this, globalObject) 45 41 { 42 RELEASE_ASSERT(!isLargeAllocation()); 46 43 } 47 44 -
trunk/Source/JavaScriptCore/runtime/JSCell.cpp
r205131 r205462 59 59 size_t JSCell::estimatedSize(JSCell* cell) 60 60 { 61 return MarkedBlock::blockFor(cell)->cellSize();61 return cell->cellSize(); 62 62 } 63 63 -
trunk/Source/JavaScriptCore/runtime/JSCell.h
r205131 r205462 81 81 enum CreatingEarlyCellTag { CreatingEarlyCell }; 82 82 JSCell(CreatingEarlyCellTag); 83 83 84 84 protected: 85 85 JSCell(VM&, Structure*); … … 108 108 109 109 const char* className() const; 110 111 VM* vm() const;112 110 113 111 // Extracting the value. … … 191 189 return OBJECT_OFFSETOF(JSCell, m_cellState); 192 190 } 191 192 void callDestructor(VM&); 193 193 194 194 static const TypedArrayType TypedArrayStorageType = NotTypedArray; -
trunk/Source/JavaScriptCore/runtime/JSCellInlines.h
r204912 r205462 114 114 } 115 115 116 inline VM* JSCell::vm() const117 {118 return MarkedBlock::blockFor(this)->vm();119 }120 121 116 ALWAYS_INLINE VM& ExecState::vm() const 122 117 { 123 118 ASSERT(callee()); 124 119 ASSERT(callee()->vm()); 125 return *calleeAsValue().asCell()->vm(); 120 ASSERT(!callee()->isLargeAllocation()); 121 // This is an important optimization since we access this so often. 122 return *calleeAsValue().asCell()->markedBlock().vm(); 126 123 } 127 124 … … 234 231 } 235 232 236 inline const ClassInfo* JSCell::classInfo() const 237 { 238 MarkedBlock* block = MarkedBlock::blockFor(this); 239 if (block->needsDestruction() && !(inlineTypeFlags() & StructureIsImmortal)) 233 ALWAYS_INLINE const ClassInfo* JSCell::classInfo() const 234 { 235 if (isLargeAllocation()) { 236 LargeAllocation& allocation = largeAllocation(); 237 if (allocation.attributes().destruction == NeedsDestruction 238 && !(inlineTypeFlags() & StructureIsImmortal)) 239 return static_cast<const JSDestructibleObject*>(this)->classInfo(); 240 return structure(*allocation.vm())->classInfo(); 241 } 242 MarkedBlock& block = markedBlock(); 243 if (block.needsDestruction() && !(inlineTypeFlags() & StructureIsImmortal)) 240 244 return static_cast<const JSDestructibleObject*>(this)->classInfo(); 241 return structure(*block ->vm())->classInfo();245 return structure(*block.vm())->classInfo(); 242 246 } 243 247 … … 258 262 } 259 263 264 inline void JSCell::callDestructor(VM& vm) 265 { 266 if (isZapped()) 267 return; 268 ASSERT(structureID()); 269 if (inlineTypeFlags() & StructureIsImmortal) 270 structure(vm)->classInfo()->methodTable.destroy(this); 271 else 272 jsCast<JSDestructibleObject*>(this)->classInfo()->methodTable.destroy(this); 273 zap(); 274 } 275 260 276 } // namespace JSC 261 277 -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r205335 r205462 65 65 JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope) 66 66 { 67 return create(vm, executable, scope, scope->globalObject( )->functionStructure());67 return create(vm, executable, scope, scope->globalObject(vm)->functionStructure()); 68 68 } 69 69 … … 79 79 { 80 80 JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope); 81 ASSERT(function->structure( )->globalObject());81 ASSERT(function->structure(vm)->globalObject()); 82 82 function->finishCreation(vm); 83 83 return function; … … 146 146 JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype)); 147 147 if (!prototype) 148 prototype = globalObject( )->objectPrototype();148 prototype = globalObject(vm)->objectPrototype(); 149 149 FunctionRareData* rareData = FunctionRareData::create(vm); 150 rareData->initializeObjectAllocationProfile( globalObject()->vm(), prototype, inlineCapacity);150 rareData->initializeObjectAllocationProfile(vm, prototype, inlineCapacity); 151 151 152 152 // A DFG compilation thread may be trying to read the rare data … … 164 164 JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype)); 165 165 if (!prototype) 166 prototype = globalObject( )->objectPrototype();167 m_rareData->initializeObjectAllocationProfile( globalObject()->vm(), prototype, inlineCapacity);166 prototype = globalObject(vm)->objectPrototype(); 167 m_rareData->initializeObjectAllocationProfile(vm, prototype, inlineCapacity); 168 168 return m_rareData.get(); 169 169 } … … 346 346 bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) 347 347 { 348 VM& vm = exec->vm(); 348 349 JSFunction* thisObject = jsCast<JSFunction*>(object); 349 350 if (thisObject->isHostOrBuiltinFunction()) { 350 thisObject->reifyBoundNameIfNeeded( exec, propertyName);351 thisObject->reifyBoundNameIfNeeded(vm, exec, propertyName); 351 352 return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); 352 353 } 353 354 354 if (propertyName == exec->propertyNames().prototype && !thisObject->jsExecutable()->isArrowFunction()) { 355 VM& vm = exec->vm(); 355 if (propertyName == vm.propertyNames->prototype && !thisObject->jsExecutable()->isArrowFunction()) { 356 356 unsigned attributes; 357 357 PropertyOffset offset = thisObject->getDirectOffset(vm, propertyName, attributes); … … 359 359 JSObject* prototype = nullptr; 360 360 if (thisObject->jsExecutable()->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode) 361 prototype = constructEmptyObject(exec, thisObject->globalObject( )->generatorPrototype());361 prototype = constructEmptyObject(exec, thisObject->globalObject(vm)->generatorPrototype()); 362 362 else 363 363 prototype = constructEmptyObject(exec); 364 364 365 prototype->putDirect(vm, exec->propertyNames().constructor, thisObject, DontEnum);366 thisObject->putDirect(vm, exec->propertyNames().prototype, prototype, DontDelete | DontEnum);367 offset = thisObject->getDirectOffset(vm, exec->propertyNames().prototype, attributes);365 prototype->putDirect(vm, vm.propertyNames->constructor, thisObject, DontEnum); 366 thisObject->putDirect(vm, vm.propertyNames->prototype, prototype, DontDelete | DontEnum); 367 offset = thisObject->getDirectOffset(vm, vm.propertyNames->prototype, attributes); 368 368 ASSERT(isValidOffset(offset)); 369 369 } … … 372 372 } 373 373 374 if (propertyName == exec->propertyNames().arguments) {374 if (propertyName == vm.propertyNames->arguments) { 375 375 if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isClassConstructorFunction()) { 376 376 bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); 377 377 if (!result) { 378 GetterSetter* errorGetterSetter = thisObject->globalObject( )->throwTypeErrorArgumentsCalleeAndCallerGetterSetter();378 GetterSetter* errorGetterSetter = thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(); 379 379 thisObject->putDirectAccessor(exec, propertyName, errorGetterSetter, DontDelete | DontEnum | Accessor); 380 380 result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); … … 387 387 } 388 388 389 if (propertyName == exec->propertyNames().caller) {389 if (propertyName == vm.propertyNames->caller) { 390 390 if (thisObject->jsExecutable()->isStrictMode() || thisObject->jsExecutable()->isClassConstructorFunction()) { 391 391 bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); 392 392 if (!result) { 393 GetterSetter* errorGetterSetter = thisObject->globalObject( )->throwTypeErrorArgumentsCalleeAndCallerGetterSetter();393 GetterSetter* errorGetterSetter = thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(); 394 394 thisObject->putDirectAccessor(exec, propertyName, errorGetterSetter, DontDelete | DontEnum | Accessor); 395 395 result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); … … 402 402 } 403 403 404 thisObject->reifyLazyPropertyIfNeeded( exec, propertyName);404 thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName); 405 405 406 406 return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); … … 438 438 439 439 if (thisObject->isHostOrBuiltinFunction()) { 440 thisObject->reifyBoundNameIfNeeded( exec, propertyName);440 thisObject->reifyBoundNameIfNeeded(vm, exec, propertyName); 441 441 return Base::put(thisObject, exec, propertyName, value, slot); 442 442 } 443 443 444 if (propertyName == exec->propertyNames().prototype) {444 if (propertyName == vm.propertyNames->prototype) { 445 445 // Make sure prototype has been reified, such that it can only be overwritten 446 446 // following the rules set out in ECMA-262 8.12.9. … … 454 454 return Base::put(thisObject, exec, propertyName, value, dontCache); 455 455 } 456 if (thisObject->jsExecutable()->isStrictMode() && (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller)) {456 if (thisObject->jsExecutable()->isStrictMode() && (propertyName == vm.propertyNames->arguments || propertyName == vm.propertyNames->caller)) { 457 457 // This will trigger the property to be reified, if this is not already the case! 458 458 bool okay = thisObject->hasProperty(exec, propertyName); … … 461 461 return Base::put(thisObject, exec, propertyName, value, slot); 462 462 } 463 if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().caller) {463 if (propertyName == vm.propertyNames->arguments || propertyName == vm.propertyNames->caller) { 464 464 if (slot.isStrictMode()) 465 465 throwTypeError(exec, scope, StrictModeReadonlyPropertyWriteError); 466 466 return false; 467 467 } 468 thisObject->reifyLazyPropertyIfNeeded( exec, propertyName);468 thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName); 469 469 scope.release(); 470 470 return Base::put(thisObject, exec, propertyName, value, slot); … … 475 475 JSFunction* thisObject = jsCast<JSFunction*>(cell); 476 476 if (thisObject->isHostOrBuiltinFunction()) 477 thisObject->reifyBoundNameIfNeeded(exec , propertyName);477 thisObject->reifyBoundNameIfNeeded(exec->vm(), exec, propertyName); 478 478 else if (exec->vm().deletePropertyMode() != VM::DeletePropertyMode::IgnoreConfigurable) { 479 479 // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty. 480 VM& vm = exec->vm(); 480 481 FunctionExecutable* executable = thisObject->jsExecutable(); 481 if (propertyName == exec->propertyNames().arguments482 || (propertyName == exec->propertyNames().prototype && !executable->isArrowFunction())483 || propertyName == exec->propertyNames().caller)482 if (propertyName == vm.propertyNames->arguments 483 || (propertyName == vm.propertyNames->prototype && !executable->isArrowFunction()) 484 || propertyName == vm.propertyNames->caller) 484 485 return false; 485 486 486 thisObject->reifyLazyPropertyIfNeeded( exec, propertyName);487 thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName); 487 488 } 488 489 … … 497 498 JSFunction* thisObject = jsCast<JSFunction*>(object); 498 499 if (thisObject->isHostOrBuiltinFunction()) { 499 thisObject->reifyBoundNameIfNeeded( exec, propertyName);500 thisObject->reifyBoundNameIfNeeded(vm, exec, propertyName); 500 501 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); 501 502 } 502 503 503 if (propertyName == exec->propertyNames().prototype) {504 if (propertyName == vm.propertyNames->prototype) { 504 505 // Make sure prototype has been reified, such that it can only be overwritten 505 506 // following the rules set out in ECMA-262 8.12.9. … … 512 513 513 514 bool valueCheck; 514 if (propertyName == exec->propertyNames().arguments) {515 if (propertyName == vm.propertyNames->arguments) { 515 516 if (thisObject->jsExecutable()->isStrictMode()) { 516 517 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry); 517 518 if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot)) 518 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject( )->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), DontDelete | DontEnum | Accessor);519 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), DontDelete | DontEnum | Accessor); 519 520 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); 520 521 } 521 522 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveArguments(exec, thisObject)); 522 } else if (propertyName == exec->propertyNames().caller) {523 } else if (propertyName == vm.propertyNames->caller) { 523 524 if (thisObject->jsExecutable()->isStrictMode()) { 524 525 PropertySlot slot(thisObject, PropertySlot::InternalMethodType::VMInquiry); 525 526 if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot)) 526 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject( )->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), DontDelete | DontEnum | Accessor);527 thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject(vm)->throwTypeErrorArgumentsCalleeAndCallerGetterSetter(), DontDelete | DontEnum | Accessor); 527 528 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); 528 529 } 529 530 valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), retrieveCallerFunction(exec, thisObject)); 530 531 } else { 531 thisObject->reifyLazyPropertyIfNeeded( exec, propertyName);532 thisObject->reifyLazyPropertyIfNeeded(vm, exec, propertyName); 532 533 return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException); 533 534 } … … 591 592 void JSFunction::setFunctionName(ExecState* exec, JSValue value) 592 593 { 594 VM& vm = exec->vm(); 593 595 // The "name" property may have been already been defined as part of a property list in an 594 596 // object literal (and therefore reified). … … 606 608 name = makeString('[', String(&uid), ']'); 607 609 } else { 608 VM& vm = exec->vm();609 610 JSString* jsStr = value.toString(exec); 610 611 if (vm.exception()) … … 614 615 return; 615 616 } 616 reifyName(exec, name); 617 } 618 619 void JSFunction::reifyLength(ExecState* exec) 620 { 621 VM& vm = exec->vm(); 617 reifyName(vm, exec, name); 618 } 619 620 void JSFunction::reifyLength(VM& vm) 621 { 622 622 FunctionRareData* rareData = this->rareData(vm); 623 623 … … 626 626 JSValue initialValue = jsNumber(jsExecutable()->parameterCount()); 627 627 unsigned initialAttributes = DontEnum | ReadOnly; 628 const Identifier& identifier = exec->propertyNames().length;628 const Identifier& identifier = vm.propertyNames->length; 629 629 putDirect(vm, identifier, initialValue, initialAttributes); 630 630 … … 632 632 } 633 633 634 void JSFunction::reifyName( ExecState* exec)634 void JSFunction::reifyName(VM& vm, ExecState* exec) 635 635 { 636 636 const Identifier& ecmaName = jsExecutable()->ecmaName(); … … 643 643 else 644 644 name = ecmaName.string(); 645 reifyName(exec, name); 646 } 647 648 void JSFunction::reifyName(ExecState* exec, String name) 649 { 650 VM& vm = exec->vm(); 645 reifyName(vm, exec, name); 646 } 647 648 void JSFunction::reifyName(VM& vm, ExecState* exec, String name) 649 { 651 650 FunctionRareData* rareData = this->rareData(vm); 652 651 … … 654 653 ASSERT(!isHostFunction()); 655 654 unsigned initialAttributes = DontEnum | ReadOnly; 656 const Identifier& propID = exec->propertyNames().name;655 const Identifier& propID = vm.propertyNames->name; 657 656 658 657 if (exec->lexicalGlobalObject()->needsSiteSpecificQuirks()) { … … 673 672 } 674 673 675 void JSFunction::reifyLazyPropertyIfNeeded( ExecState* exec, PropertyName propertyName)676 { 677 if (propertyName == exec->propertyNames().length) {674 void JSFunction::reifyLazyPropertyIfNeeded(VM& vm, ExecState* exec, PropertyName propertyName) 675 { 676 if (propertyName == vm.propertyNames->length) { 678 677 if (!hasReifiedLength()) 679 reifyLength( exec);680 } else if (propertyName == exec->propertyNames().name) {678 reifyLength(vm); 679 } else if (propertyName == vm.propertyNames->name) { 681 680 if (!hasReifiedName()) 682 reifyName( exec);683 } 684 } 685 686 void JSFunction::reifyBoundNameIfNeeded( ExecState* exec, PropertyName propertyName)687 { 688 const Identifier& nameIdent = exec->propertyNames().name;681 reifyName(vm, exec); 682 } 683 } 684 685 void JSFunction::reifyBoundNameIfNeeded(VM& vm, ExecState* exec, PropertyName propertyName) 686 { 687 const Identifier& nameIdent = vm.propertyNames->name; 689 688 if (propertyName != nameIdent) 690 689 return; … … 694 693 695 694 if (this->inherits(JSBoundFunction::info())) { 696 VM& vm = exec->vm();697 695 FunctionRareData* rareData = this->rareData(vm); 698 696 String name = makeString("bound ", static_cast<NativeExecutable*>(m_executable.get())->name()); -
trunk/Source/JavaScriptCore/runtime/JSFunction.h
r204912 r205462 190 190 bool hasReifiedLength() const; 191 191 bool hasReifiedName() const; 192 void reifyLength( ExecState*);193 void reifyName( ExecState*);194 void reifyBoundNameIfNeeded( ExecState*, PropertyName);195 void reifyName( ExecState*, String name);196 void reifyLazyPropertyIfNeeded( ExecState*, PropertyName propertyName);192 void reifyLength(VM&); 193 void reifyName(VM&, ExecState*); 194 void reifyBoundNameIfNeeded(VM&, ExecState*, PropertyName); 195 void reifyName(VM&, ExecState*, String name); 196 void reifyLazyPropertyIfNeeded(VM&, ExecState*, PropertyName propertyName); 197 197 198 198 friend class LLIntOffsetsExtractor; -
trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h
r204912 r205462 36 36 { 37 37 ASSERT(executable->singletonFunction()->hasBeenInvalidated()); 38 return createImpl(vm, executable, scope, scope->globalObject( )->functionStructure());38 return createImpl(vm, executable, scope, scope->globalObject(vm)->functionStructure()); 39 39 } 40 40 … … 48 48 #if ENABLE(WEBASSEMBLY) 49 49 inline JSFunction::JSFunction(VM& vm, WebAssemblyExecutable* executable, JSScope* scope) 50 : Base(vm, scope, scope->globalObject( )->functionStructure())50 : Base(vm, scope, scope->globalObject(vm)->functionStructure()) 51 51 , m_executable(vm, this, executable) 52 52 , m_rareData() -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
r205198 r205462 521 521 // that you *had* done those allocations and it will GC appropriately. 522 522 Heap* heap = Heap::heap(thisObject); 523 VM& vm = *heap->vm(); 523 524 DeferGCForAWhile deferGC(*heap); 524 525 525 526 ASSERT(!thisObject->hasIndexingHeader()); 526 527 527 size_t size = thisObject->byteSize(); 528 529 if (thisObject->m_mode == FastTypedArray 530 && !thisObject->butterfly() && size >= sizeof(IndexingHeader)) { 531 ASSERT(thisObject->m_vector); 532 // Reuse already allocated memory if at all possible. 533 thisObject->m_butterfly.setWithoutBarrier( 534 bitwise_cast<IndexingHeader*>(thisObject->vector())->butterfly()); 535 } else { 536 RELEASE_ASSERT(!thisObject->hasIndexingHeader()); 537 VM& vm = *heap->vm(); 538 thisObject->m_butterfly.set(vm, thisObject, Butterfly::createOrGrowArrayRight( 539 thisObject->butterfly(), vm, thisObject, thisObject->structure(), 540 thisObject->structure()->outOfLineCapacity(), false, 0, 0)); 541 } 528 RELEASE_ASSERT(!thisObject->hasIndexingHeader()); 529 thisObject->m_butterfly.set(vm, thisObject, Butterfly::createOrGrowArrayRight( 530 thisObject->butterfly(), vm, thisObject, thisObject->structure(), 531 thisObject->structure()->outOfLineCapacity(), false, 0, 0)); 542 532 543 533 RefPtr<ArrayBuffer> buffer; -
trunk/Source/JavaScriptCore/runtime/JSInternalPromise.cpp
r205324 r205462 28 28 29 29 #include "BuiltinNames.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 32 #include "JSObjectInlines.h" 33 #include "StructureInlines.h" 30 #include "JSCInlines.h" 34 31 35 32 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.cpp
r204912 r205462 28 28 29 29 #include "JSCBuiltins.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 32 31 #include "JSInternalPromise.h" 33 32 #include "JSInternalPromisePrototype.h" 34 #include "StructureInlines.h"35 33 36 34 #include "JSInternalPromiseConstructor.lut.h" -
trunk/Source/JavaScriptCore/runtime/JSInternalPromiseDeferred.cpp
r205324 r205462 30 30 #include "Error.h" 31 31 #include "Exception.h" 32 #include "JSCJSValueInlines.h" 33 #include "JSCellInlines.h" 32 #include "JSCInlines.h" 34 33 #include "JSInternalPromise.h" 35 34 #include "JSInternalPromiseConstructor.h" 36 #include "JSObjectInlines.h"37 #include "SlotVisitorInlines.h"38 #include "StructureInlines.h"39 35 40 36 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSInternalPromisePrototype.cpp
r204912 r205462 29 29 #include "Error.h" 30 30 #include "JSCBuiltins.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 31 #include "JSCInlines.h" 33 32 #include "JSGlobalObject.h" 34 33 #include "JSInternalPromise.h" 35 34 #include "Microtask.h" 36 #include "StructureInlines.h"37 35 38 36 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSJob.cpp
r205324 r205462 29 29 #include "Error.h" 30 30 #include "Exception.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 31 #include "JSCInlines.h" 33 32 #include "JSGlobalObject.h" 34 33 #include "JSObjectInlines.h" 35 34 #include "Microtask.h" 36 #include "SlotVisitorInlines.h"37 35 #include "StrongInlines.h" 38 36 -
trunk/Source/JavaScriptCore/runtime/JSMapIterator.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2013 Apple, Inc. All rights reserved.2 * Copyright (C) 2013, 2016 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "JSMapIterator.h" 28 28 29 #include "JSCJSValueInlines.h" 30 #include "JSCellInlines.h" 29 #include "JSCInlines.h" 31 30 #include "JSMap.h" 32 31 #include "MapDataInlines.h" 33 #include "SlotVisitorInlines.h"34 #include "StructureInlines.h"35 32 36 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp
r205198 r205462 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include "Error.h" 30 #include "IdentifierInlines.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 33 31 #include "JSModuleEnvironment.h" 34 32 #include "JSModuleRecord.h" 35 33 #include "JSPropertyNameIterator.h" 36 #include "SlotVisitorInlines.h"37 #include "StructureInlines.h"38 34 39 35 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSModuleRecord.cpp
r205324 r205462 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "Error.h" 30 30 #include "Executable.h" 31 #include "IdentifierInlines.h" 32 #include "JSCJSValueInlines.h" 33 #include "JSCellInlines.h" 31 #include "Interpreter.h" 32 #include "JSCInlines.h" 34 33 #include "JSMap.h" 35 34 #include "JSModuleEnvironment.h" 36 35 #include "JSModuleNamespaceObject.h" 37 #include "JSObjectInlines.h"38 #include "SlotVisitorInlines.h"39 #include "StructureInlines.h"40 36 41 37 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSObject.cpp
r205372 r205462 89 89 } 90 90 91 ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butterfly, size_t storageSize)92 {93 ASSERT(butterfly);94 95 Structure* structure = this->structure();96 97 size_t propertyCapacity = structure->outOfLineCapacity();98 size_t preCapacity;99 size_t indexingPayloadSizeInBytes;100 bool hasIndexingHeader = this->hasIndexingHeader();101 if (UNLIKELY(hasIndexingHeader)) {102 preCapacity = butterfly->indexingHeader()->preCapacity(structure);103 indexingPayloadSizeInBytes = butterfly->indexingHeader()->indexingPayloadSizeInBytes(structure);104 } else {105 preCapacity = 0;106 indexingPayloadSizeInBytes = 0;107 }108 size_t capacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);109 if (visitor.checkIfShouldCopy(butterfly->base(preCapacity, propertyCapacity))) {110 Butterfly* newButterfly = Butterfly::createUninitializedDuringCollection(visitor, preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes);111 112 // Copy the properties.113 PropertyStorage currentTarget = newButterfly->propertyStorage();114 PropertyStorage currentSource = butterfly->propertyStorage();115 for (size_t count = storageSize; count--;)116 (--currentTarget)->setWithoutWriteBarrier((--currentSource)->get());117 118 if (UNLIKELY(hasIndexingHeader)) {119 *newButterfly->indexingHeader() = *butterfly->indexingHeader();120 121 // Copy the array if appropriate.122 123 WriteBarrier<Unknown>* currentTarget;124 WriteBarrier<Unknown>* currentSource;125 size_t count;126 127 switch (this->indexingType()) {128 case ALL_UNDECIDED_INDEXING_TYPES:129 case ALL_CONTIGUOUS_INDEXING_TYPES:130 case ALL_INT32_INDEXING_TYPES:131 case ALL_DOUBLE_INDEXING_TYPES: {132 currentTarget = newButterfly->contiguous().data();133 currentSource = butterfly->contiguous().data();134 RELEASE_ASSERT(newButterfly->publicLength() <= newButterfly->vectorLength());135 count = newButterfly->vectorLength();136 break;137 }138 139 case ALL_ARRAY_STORAGE_INDEXING_TYPES: {140 newButterfly->arrayStorage()->copyHeaderFromDuringGC(*butterfly->arrayStorage());141 currentTarget = newButterfly->arrayStorage()->m_vector;142 currentSource = butterfly->arrayStorage()->m_vector;143 count = newButterfly->arrayStorage()->vectorLength();144 break;145 }146 147 default:148 currentTarget = 0;149 currentSource = 0;150 count = 0;151 break;152 }153 154 memcpy(currentTarget, currentSource, count * sizeof(EncodedJSValue));155 }156 157 m_butterfly.setWithoutBarrier(newButterfly);158 visitor.didCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes);159 }160 }161 162 91 ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* butterfly, Structure* structure) 163 92 { … … 167 96 size_t propertyCapacity = structure->outOfLineCapacity(); 168 97 size_t preCapacity; 169 size_t indexingPayloadSizeInBytes;170 98 bool hasIndexingHeader = this->hasIndexingHeader(); 171 if (UNLIKELY(hasIndexingHeader)) {99 if (UNLIKELY(hasIndexingHeader)) 172 100 preCapacity = butterfly->indexingHeader()->preCapacity(structure); 173 indexingPayloadSizeInBytes = butterfly->indexingHeader()->indexingPayloadSizeInBytes(structure); 174 } else { 101 else 175 102 preCapacity = 0; 176 indexingPayloadSizeInBytes = 0; 177 } 178 size_t capacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); 179 103 104 HeapCell* base = bitwise_cast<HeapCell*>(butterfly->base(preCapacity, propertyCapacity)); 105 106 ASSERT(Heap::heap(base) == visitor.heap()); 107 108 // Keep the butterfly alive. 109 visitor.markAuxiliary(base); 110 180 111 // Mark the properties. 181 112 visitor.appendValuesHidden(butterfly->propertyStorage() - storageSize, storageSize); 182 visitor.copyLater(183 this, ButterflyCopyToken,184 butterfly->base(preCapacity, propertyCapacity), capacityInBytes);185 113 186 114 // Mark the array if appropriate. … … 224 152 visitor.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation; 225 153 #endif 226 }227 228 void JSObject::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)229 {230 JSObject* thisObject = jsCast<JSObject*>(cell);231 ASSERT_GC_OBJECT_INHERITS(thisObject, info());232 233 if (token != ButterflyCopyToken)234 return;235 236 Butterfly* butterfly = thisObject->m_butterfly.get();237 if (butterfly)238 thisObject->copyButterfly(visitor, butterfly, thisObject->structure()->outOfLineSize());239 154 } 240 155 … … 784 699 return; 785 700 786 globalObject( )->haveABadTime(vm);787 } 788 789 Butterfly* JSObject::createInitialIndexedStorage(VM& vm, unsigned length , size_t elementSize)701 globalObject(vm)->haveABadTime(vm); 702 } 703 704 Butterfly* JSObject::createInitialIndexedStorage(VM& vm, unsigned length) 790 705 { 791 706 ASSERT(length < MAX_ARRAY_INDEX); … … 794 709 ASSERT(!structure()->needsSlowPutIndexing()); 795 710 ASSERT(!indexingShouldBeSparse()); 796 unsigned vectorLength = std::max(length, BASE_VECTOR_LEN); 711 Structure* structure = this->structure(vm); 712 unsigned propertyCapacity = structure->outOfLineCapacity(); 713 unsigned vectorLength = Butterfly::optimalContiguousVectorLength(propertyCapacity, length); 797 714 Butterfly* newButterfly = Butterfly::createOrGrowArrayRight( 798 m_butterfly.get(), vm, this, structure (), structure()->outOfLineCapacity(), false, 0,799 elementSize* vectorLength);715 m_butterfly.get(), vm, this, structure, propertyCapacity, false, 0, 716 sizeof(EncodedJSValue) * vectorLength); 800 717 newButterfly->setPublicLength(length); 801 718 newButterfly->setVectorLength(vectorLength); … … 806 723 { 807 724 DeferGC deferGC(vm.heap); 808 Butterfly* newButterfly = createInitialIndexedStorage(vm, length , sizeof(EncodedJSValue));725 Butterfly* newButterfly = createInitialIndexedStorage(vm, length); 809 726 Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), NonPropertyTransition::AllocateUndecided); 810 727 setStructureAndButterfly(vm, newStructure, newButterfly); … … 815 732 { 816 733 DeferGC deferGC(vm.heap); 817 Butterfly* newButterfly = createInitialIndexedStorage(vm, length, sizeof(EncodedJSValue)); 734 Butterfly* newButterfly = createInitialIndexedStorage(vm, length); 735 for (unsigned i = newButterfly->vectorLength(); i--;) 736 newButterfly->contiguousInt32()[i].setWithoutWriteBarrier(JSValue()); 818 737 Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), NonPropertyTransition::AllocateInt32); 819 738 setStructureAndButterfly(vm, newStructure, newButterfly); … … 824 743 { 825 744 DeferGC deferGC(vm.heap); 826 Butterfly* newButterfly = createInitialIndexedStorage(vm, length , sizeof(double));745 Butterfly* newButterfly = createInitialIndexedStorage(vm, length); 827 746 for (unsigned i = newButterfly->vectorLength(); i--;) 828 747 newButterfly->contiguousDouble()[i] = PNaN; … … 835 754 { 836 755 DeferGC deferGC(vm.heap); 837 Butterfly* newButterfly = createInitialIndexedStorage(vm, length, sizeof(EncodedJSValue)); 756 Butterfly* newButterfly = createInitialIndexedStorage(vm, length); 757 for (unsigned i = newButterfly->vectorLength(); i--;) 758 newButterfly->contiguous()[i].setWithoutWriteBarrier(JSValue()); 838 759 Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), NonPropertyTransition::AllocateContiguous); 839 760 setStructureAndButterfly(vm, newStructure, newButterfly); … … 858 779 result->m_numValuesInVector = 0; 859 780 result->m_indexBias = 0; 781 for (size_t i = vectorLength; i--;) 782 result->m_vector[i].setWithoutWriteBarrier(JSValue()); 860 783 Structure* newStructure = Structure::nonPropertyTransition(vm, structure, structure->suggestedArrayStorageTransition()); 861 784 setStructureAndButterfly(vm, newStructure, newButterfly); … … 865 788 ArrayStorage* JSObject::createInitialArrayStorage(VM& vm) 866 789 { 867 return createArrayStorage(vm, 0, BASE_VECTOR_LEN); 790 return createArrayStorage( 791 vm, 0, ArrayStorage::optimalVectorLength(0, structure(vm)->outOfLineCapacity(), 0)); 868 792 } 869 793 … … 871 795 { 872 796 ASSERT(hasUndecided(indexingType())); 797 798 Butterfly* butterfly = m_butterfly.get(); 799 for (unsigned i = butterfly->vectorLength(); i--;) 800 butterfly->contiguousInt32()[i].setWithoutWriteBarrier(JSValue()); 801 873 802 setStructure(vm, Structure::nonPropertyTransition(vm, structure(vm), NonPropertyTransition::AllocateInt32)); 874 803 return m_butterfly.get()->contiguousInt32(); … … 890 819 { 891 820 ASSERT(hasUndecided(indexingType())); 821 822 Butterfly* butterfly = m_butterfly.get(); 823 for (unsigned i = butterfly->vectorLength(); i--;) 824 butterfly->contiguous()[i].setWithoutWriteBarrier(JSValue()); 825 892 826 setStructure(vm, Structure::nonPropertyTransition(vm, structure(vm), NonPropertyTransition::AllocateContiguous)); 893 827 return m_butterfly.get()->contiguous(); … … 926 860 unsigned vectorLength = m_butterfly.get()->vectorLength(); 927 861 ArrayStorage* storage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength); 928 // No need to copy elements. 862 863 for (unsigned i = vectorLength; i--;) 864 storage->m_vector[i].setWithoutWriteBarrier(JSValue()); 929 865 930 866 Structure* newStructure = Structure::nonPropertyTransition(vm, structure(vm), transition); … … 947 883 double* currentAsDouble = bitwise_cast<double*>(current); 948 884 JSValue v = current->get(); 949 if (!v) { 885 // NOTE: Since this may be used during initialization, v could be garbage. If it's garbage, 886 // that means it will be overwritten later. 887 if (!v.isInt32()) { 950 888 *currentAsDouble = PNaN; 951 889 continue; 952 890 } 953 ASSERT(v.isInt32());954 891 *currentAsDouble = v.asInt32(); 955 892 } … … 975 912 ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength); 976 913 Butterfly* butterfly = m_butterfly.get(); 977 for (unsigned i = 0; i < butterfly->publicLength(); i++) {914 for (unsigned i = 0; i < vectorLength; i++) { 978 915 JSValue v = butterfly->contiguous()[i].get(); 979 if (v) {980 newStorage->m_vector[i].setWithoutWriteBarrier(v);916 newStorage->m_vector[i].setWithoutWriteBarrier(v); 917 if (v) 981 918 newStorage->m_numValuesInVector++; 982 } else983 ASSERT(newStorage->m_vector[i].get().isEmpty());984 919 } 985 920 … … 1023 958 ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength); 1024 959 Butterfly* butterfly = m_butterfly.get(); 1025 for (unsigned i = 0; i < butterfly->publicLength(); i++) {960 for (unsigned i = 0; i < vectorLength; i++) { 1026 961 double value = butterfly->contiguousDouble()[i]; 1027 if (value == value) {1028 newStorage->m_vector[i].setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value));962 newStorage->m_vector[i].setWithoutWriteBarrier(JSValue(JSValue::EncodeAsDouble, value)); 963 if (value == value) 1029 964 newStorage->m_numValuesInVector++; 1030 } else1031 ASSERT(newStorage->m_vector[i].get().isEmpty());1032 965 } 1033 966 … … 1050 983 ArrayStorage* newStorage = constructConvertedArrayStorageWithoutCopyingElements(vm, vectorLength); 1051 984 Butterfly* butterfly = m_butterfly.get(); 1052 for (unsigned i = 0; i < butterfly->publicLength(); i++) {985 for (unsigned i = 0; i < vectorLength; i++) { 1053 986 JSValue v = butterfly->contiguous()[i].get(); 1054 if (v) {1055 newStorage->m_vector[i].setWithoutWriteBarrier(v);987 newStorage->m_vector[i].setWithoutWriteBarrier(v); 988 if (v) 1056 989 newStorage->m_numValuesInVector++; 1057 } else1058 ASSERT(newStorage->m_vector[i].get().isEmpty());1059 990 } 1060 991 … … 2407 2338 if (structure(vm)->needsSlowPutIndexing()) { 2408 2339 // Convert the indexing type to the SlowPutArrayStorage and retry. 2409 createArrayStorage(vm, i + 1, getNewVectorLength(0, 0, i + 1));2340 createArrayStorage(vm, i + 1, getNewVectorLength(0, 0, 0, i + 1)); 2410 2341 return putByIndex(this, exec, i, value, shouldThrow); 2411 2342 } … … 2548 2479 } 2549 2480 if (structure(vm)->needsSlowPutIndexing()) { 2550 ArrayStorage* storage = createArrayStorage(vm, i + 1, getNewVectorLength(0, 0, i + 1));2481 ArrayStorage* storage = createArrayStorage(vm, i + 1, getNewVectorLength(0, 0, 0, i + 1)); 2551 2482 storage->m_vector[i].set(vm, this, value); 2552 2483 storage->m_numValuesInVector++; … … 2667 2598 } 2668 2599 2669 ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned currentVectorLength, unsigned currentLength, unsigned desiredLength) 2600 // NOTE: This method is for ArrayStorage vectors. 2601 ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned indexBias, unsigned currentVectorLength, unsigned currentLength, unsigned desiredLength) 2670 2602 { 2671 2603 ASSERT(desiredLength <= MAX_STORAGE_VECTOR_LENGTH); … … 2684 2616 ASSERT(increasedLength >= desiredLength); 2685 2617 2686 lastArraySize = std::min(increasedLength, FIRST_VECTOR_GROW); 2687 2688 return std::min(increasedLength, MAX_STORAGE_VECTOR_LENGTH); 2618 lastArraySize = std::min(increasedLength, FIRST_ARRAY_STORAGE_VECTOR_GROW); 2619 2620 return ArrayStorage::optimalVectorLength( 2621 indexBias, structure()->outOfLineCapacity(), 2622 std::min(increasedLength, MAX_STORAGE_VECTOR_LENGTH)); 2689 2623 } 2690 2624 2691 2625 ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength) 2692 2626 { 2693 unsigned vectorLength; 2694 unsigned length; 2627 unsigned indexBias = 0; 2628 unsigned vectorLength = 0; 2629 unsigned length = 0; 2695 2630 2696 2631 if (hasIndexedProperties(indexingType())) { 2632 if (ArrayStorage* storage = arrayStorageOrNull()) 2633 indexBias = storage->m_indexBias; 2697 2634 vectorLength = m_butterfly.get()->vectorLength(); 2698 2635 length = m_butterfly.get()->publicLength(); 2699 } else { 2700 vectorLength = 0; 2701 length = 0; 2702 } 2703 2704 return getNewVectorLength(vectorLength, length, desiredLength); 2636 } 2637 2638 return getNewVectorLength(indexBias, vectorLength, length, desiredLength); 2705 2639 } 2706 2640 … … 2755 2689 bool JSObject::increaseVectorLength(VM& vm, unsigned newLength) 2756 2690 { 2691 ArrayStorage* storage = arrayStorage(); 2692 2693 unsigned vectorLength = storage->vectorLength(); 2694 unsigned availableVectorLength = storage->availableVectorLength(structure(vm), vectorLength); 2695 if (availableVectorLength >= newLength) { 2696 // The cell was already big enough for the desired length! 2697 for (unsigned i = vectorLength; i < availableVectorLength; ++i) 2698 storage->m_vector[i].clear(); 2699 storage->setVectorLength(availableVectorLength); 2700 return true; 2701 } 2702 2757 2703 // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map 2758 2704 // to the vector. Callers have to account for that, because they can do it more efficiently. … … 2760 2706 return false; 2761 2707 2762 ArrayStorage* storage = arrayStorage();2763 2764 2708 if (newLength >= MIN_SPARSE_ARRAY_INDEX 2765 2709 && !isDenseEnoughForVector(newLength, storage->m_numValuesInVector)) … … 2767 2711 2768 2712 unsigned indexBias = storage->m_indexBias; 2769 unsigned vectorLength = storage->vectorLength();2770 2713 ASSERT(newLength > vectorLength); 2771 2714 unsigned newVectorLength = getNewVectorLength(newLength); … … 2780 2723 if (!newButterfly) 2781 2724 return false; 2725 for (unsigned i = vectorLength; i < newVectorLength; ++i) 2726 newButterfly->arrayStorage()->m_vector[i].clear(); 2782 2727 newButterfly->arrayStorage()->setVectorLength(newVectorLength); 2783 2728 setButterflyWithoutChangingStructure(vm, newButterfly); … … 2794 2739 if (!newButterfly) 2795 2740 return false; 2741 for (unsigned i = vectorLength; i < newVectorLength; ++i) 2742 newButterfly->arrayStorage()->m_vector[i].clear(); 2796 2743 newButterfly->arrayStorage()->setVectorLength(newVectorLength); 2797 2744 newButterfly->arrayStorage()->m_indexBias = newIndexBias; … … 2808 2755 ASSERT(length > butterfly->vectorLength()); 2809 2756 2810 unsigned newVectorLength = std::min(2811 length << 1,2812 MAX_STORAGE_VECTOR_LENGTH);2813 2757 unsigned oldVectorLength = butterfly->vectorLength(); 2814 DeferGC deferGC(vm.heap); 2815 butterfly = butterfly->growArrayRight( 2816 vm, this, structure(), structure()->outOfLineCapacity(), true, 2817 oldVectorLength * sizeof(EncodedJSValue), 2818 newVectorLength * sizeof(EncodedJSValue)); 2819 if (!butterfly) 2820 return false; 2821 m_butterfly.set(vm, this, butterfly); 2758 unsigned newVectorLength; 2759 2760 Structure* structure = this->structure(vm); 2761 unsigned propertyCapacity = structure->outOfLineCapacity(); 2762 2763 unsigned availableOldLength = 2764 Butterfly::availableContiguousVectorLength(propertyCapacity, oldVectorLength); 2765 if (availableOldLength >= length) { 2766 // This is the case where someone else selected a vector length that caused internal 2767 // fragmentation. If we did our jobs right, this would never happen. But I bet we will mess 2768 // this up, so this defense should stay. 2769 newVectorLength = availableOldLength; 2770 } else { 2771 newVectorLength = Butterfly::optimalContiguousVectorLength( 2772 propertyCapacity, std::min(length << 1, MAX_STORAGE_VECTOR_LENGTH)); 2773 butterfly = butterfly->growArrayRight( 2774 vm, this, structure, propertyCapacity, true, 2775 oldVectorLength * sizeof(EncodedJSValue), 2776 newVectorLength * sizeof(EncodedJSValue)); 2777 if (!butterfly) 2778 return false; 2779 m_butterfly.set(vm, this, butterfly); 2780 } 2822 2781 2823 2782 butterfly->setVectorLength(newVectorLength); … … 2825 2784 if (hasDouble(indexingType())) { 2826 2785 for (unsigned i = oldVectorLength; i < newVectorLength; ++i) 2827 butterfly->contiguousDouble().data()[i] = PNaN; 2828 } 2786 butterfly->contiguousDouble()[i] = PNaN; 2787 } else { 2788 for (unsigned i = oldVectorLength; i < newVectorLength; ++i) 2789 butterfly->contiguous()[i].clear(); 2790 } 2791 2829 2792 return true; 2830 2793 } -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r205372 r205462 27 27 #include "ArrayConventions.h" 28 28 #include "ArrayStorage.h" 29 #include "AuxiliaryBarrier.h" 29 30 #include "Butterfly.h" 30 31 #include "CallFrame.h" 31 32 #include "ClassInfo.h" 32 33 #include "CommonIdentifiers.h" 33 #include "CopyBarrier.h"34 34 #include "CustomGetterSetter.h" 35 35 #include "DeferGC.h" 36 36 #include "Heap.h" 37 #include "HeapInlines.h"38 37 #include "IndexingHeaderInlines.h" 39 38 #include "JSCell.h" … … 104 103 JS_EXPORT_PRIVATE static size_t estimatedSize(JSCell*); 105 104 JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); 106 JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);107 105 JS_EXPORT_PRIVATE static void heapSnapshot(JSCell*, HeapSnapshotBuilder&); 108 106 … … 421 419 } 422 420 421 // NOTE: Clients of this method may call it more than once for any index, and this is supposed 422 // to work. 423 423 void initializeIndex(VM& vm, unsigned i, JSValue v, IndexingType indexingType) 424 424 { … … 693 693 void setStructure(VM&, Structure*); 694 694 void setStructureAndButterfly(VM&, Structure*, Butterfly*); 695 void setStructureAndReallocateStorageIfNecessary(VM&, unsigned oldCapacity, Structure*);696 void setStructureAndReallocateStorageIfNecessary(VM&, Structure*);697 695 698 696 JS_EXPORT_PRIVATE void convertToDictionary(VM&); … … 709 707 ASSERT(!isGlobalObject() || ((JSObject*)structure()->globalObject()) == this); 710 708 return structure()->globalObject(); 709 } 710 711 JSGlobalObject* globalObject(VM& vm) const 712 { 713 ASSERT(structure(vm)->globalObject()); 714 ASSERT(!isGlobalObject() || ((JSObject*)structure()->globalObject()) == this); 715 return structure(vm)->globalObject(); 711 716 } 712 717 … … 804 809 805 810 void visitButterfly(SlotVisitor&, Butterfly*, Structure*); 806 void copyButterfly(CopyVisitor&, Butterfly*, size_t storageSize);807 811 808 812 // Call this if you know that the object is in a mode where it has array … … 915 919 void isString(); 916 920 917 Butterfly* createInitialIndexedStorage(VM&, unsigned length , size_t elementSize);921 Butterfly* createInitialIndexedStorage(VM&, unsigned length); 918 922 919 923 ArrayStorage* enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(VM&, ArrayStorage*); … … 939 943 JS_EXPORT_PRIVATE bool putDirectIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, unsigned attributes, PutDirectIndexMode); 940 944 941 unsigned getNewVectorLength(unsigned currentVectorLength, unsigned currentLength, unsigned desiredLength);945 unsigned getNewVectorLength(unsigned indexBias, unsigned currentVectorLength, unsigned currentLength, unsigned desiredLength); 942 946 unsigned getNewVectorLength(unsigned desiredLength); 943 947 … … 956 960 957 961 protected: 958 CopyBarrier<Butterfly> m_butterfly;962 AuxiliaryBarrier<Butterfly*> m_butterfly; 959 963 #if USE(JSVALUE32_64) 960 964 private: … … 1418 1422 validateOffset(offset); 1419 1423 ASSERT(newStructure->isValidOffset(offset)); 1420 setStructureAndReallocateStorageIfNecessary(vm, newStructure); 1421 1424 DeferGC deferGC(vm.heap); 1425 size_t oldCapacity = structure->outOfLineCapacity(); 1426 size_t newCapacity = newStructure->outOfLineCapacity(); 1427 ASSERT(oldCapacity <= newCapacity); 1428 if (oldCapacity == newCapacity) 1429 setStructure(vm, newStructure); 1430 else { 1431 Butterfly* newButterfly = growOutOfLineStorage(vm, oldCapacity, newCapacity); 1432 setStructureAndButterfly(vm, newStructure, newButterfly); 1433 } 1422 1434 putDirect(vm, offset, value); 1423 1435 slot.setNewProperty(this, offset); … … 1425 1437 newStructure->setContainsReadOnlyProperties(); 1426 1438 return true; 1427 }1428 1429 inline void JSObject::setStructureAndReallocateStorageIfNecessary(VM& vm, unsigned oldCapacity, Structure* newStructure)1430 {1431 ASSERT(oldCapacity <= newStructure->outOfLineCapacity());1432 1433 if (oldCapacity == newStructure->outOfLineCapacity()) {1434 setStructure(vm, newStructure);1435 return;1436 }1437 1438 DeferGC deferGC(vm.heap);1439 Butterfly* newButterfly = growOutOfLineStorage(1440 vm, oldCapacity, newStructure->outOfLineCapacity());1441 setStructureAndButterfly(vm, newStructure, newButterfly);1442 }1443 1444 inline void JSObject::setStructureAndReallocateStorageIfNecessary(VM& vm, Structure* newStructure)1445 {1446 setStructureAndReallocateStorageIfNecessary(1447 vm, structure(vm)->outOfLineCapacity(), newStructure);1448 1439 } 1449 1440 -
trunk/Source/JavaScriptCore/runtime/JSObjectInlines.h
r205324 r205462 2 2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) 3 3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) 4 * Copyright (C) 2003-2006, 2008, 2009, 2012-201 5Apple Inc. All rights reserved.4 * Copyright (C) 2003-2006, 2008, 2009, 2012-2016 Apple Inc. All rights reserved. 5 5 * Copyright (C) 2007 Eric Seidel (eric@webkit.org) 6 6 * … … 25 25 #define JSObjectInlines_h 26 26 27 #include "AuxiliaryBarrierInlines.h" 27 28 #include "Error.h" 28 29 #include "JSObject.h" -
trunk/Source/JavaScriptCore/runtime/JSPromise.cpp
r204912 r205462 29 29 #include "BuiltinNames.h" 30 30 #include "Error.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 31 #include "JSCInlines.h" 33 32 #include "JSPromiseConstructor.h" 34 33 #include "Microtask.h" 35 #include "SlotVisitorInlines.h"36 #include "StructureInlines.h"37 34 38 35 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
r205198 r205462 33 33 #include "IteratorOperations.h" 34 34 #include "JSCBuiltins.h" 35 #include "JSCJSValueInlines.h" 36 #include "JSCellInlines.h" 35 #include "JSCInlines.h" 37 36 #include "JSFunction.h" 38 37 #include "JSPromise.h" … … 40 39 #include "Lookup.h" 41 40 #include "NumberObject.h" 42 #include "StructureInlines.h"43 41 44 42 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSPromiseDeferred.cpp
r205324 r205462 30 30 #include "Error.h" 31 31 #include "Exception.h" 32 #include "JSCJSValueInlines.h" 33 #include "JSCellInlines.h" 32 #include "JSCInlines.h" 34 33 #include "JSObjectInlines.h" 35 34 #include "JSPromise.h" 36 35 #include "JSPromiseConstructor.h" 37 #include "SlotVisitorInlines.h"38 #include "StructureInlines.h"39 36 40 37 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSPromisePrototype.cpp
r204912 r205462 30 30 #include "Error.h" 31 31 #include "JSCBuiltins.h" 32 #include "JSCJSValueInlines.h" 33 #include "JSCellInlines.h" 32 #include "JSCInlines.h" 34 33 #include "JSFunction.h" 35 34 #include "JSGlobalObject.h" 36 35 #include "JSPromise.h" 37 36 #include "Microtask.h" 38 #include "StructureInlines.h"39 37 40 38 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
r205198 r205462 1 1 /* 2 * Copyright (C) 2015 Apple, Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "JSPropertyNameIterator.h" 28 28 29 #include "IdentifierInlines.h"30 29 #include "IteratorOperations.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 33 31 #include "JSPropertyNameEnumerator.h" 34 #include "SlotVisitorInlines.h"35 #include "StructureInlines.h"36 32 37 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSScope.cpp
r204912 r205462 218 218 JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident) 219 219 { 220 VM& vm = exec->vm(); 220 221 ScopeChainIterator end = scope->end(); 221 222 ScopeChainIterator it = scope->begin(); … … 226 227 // Global scope. 227 228 if (++it == end) { 228 JSScope* globalScopeExtension = scope->globalObject( )->globalScopeExtension();229 JSScope* globalScopeExtension = scope->globalObject(vm)->globalScopeExtension(); 229 230 if (UNLIKELY(globalScopeExtension)) { 230 231 if (object->hasProperty(exec, ident)) -
trunk/Source/JavaScriptCore/runtime/JSScope.h
r204912 r205462 70 70 71 71 JSGlobalObject* globalObject(); 72 VM* vm();72 JSGlobalObject* globalObject(VM&); 73 73 JSObject* globalThis(); 74 74 … … 130 130 } 131 131 132 inline VM* JSScope::vm()132 inline JSGlobalObject* JSScope::globalObject(VM& vm) 133 133 { 134 return MarkedBlock::blockFor(this)->vm();134 return structure(vm)->globalObject(); 135 135 } 136 136 -
trunk/Source/JavaScriptCore/runtime/JSSetIterator.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2013 Apple, Inc. All rights reserved.2 * Copyright (C) 2013, 2016 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "JSSetIterator.h" 28 28 29 #include "JSCJSValueInlines.h" 30 #include "JSCellInlines.h" 29 #include "JSCInlines.h" 31 30 #include "JSSet.h" 32 31 #include "MapDataInlines.h" 33 #include "SlotVisitorInlines.h"34 #include "StructureInlines.h"35 32 36 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSStringIterator.cpp
r204912 r205462 29 29 30 30 #include "BuiltinNames.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 33 #include "StructureInlines.h" 31 #include "JSCInlines.h" 34 32 35 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSTemplateRegistryKey.cpp
r204912 r205462 1 1 /* 2 2 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>. 3 * Copyright (C) 2016 Apple Inc. All Rights Reserved. 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 27 28 #include "JSTemplateRegistryKey.h" 28 29 29 #include "JSCJSValueInlines.h" 30 #include "JSCellInlines.h" 31 #include "StructureInlines.h" 30 #include "JSCInlines.h" 32 31 #include "VM.h" 33 32 -
trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewConstructor.cpp
r205198 r205462 31 31 #include "GetterSetter.h" 32 32 #include "JSCBuiltins.h" 33 #include "JSC ellInlines.h"33 #include "JSCInlines.h" 34 34 #include "JSGenericTypedArrayViewConstructorInlines.h" 35 #include "JSObject.h"36 35 #include "JSTypedArrayViewPrototype.h" 37 36 #include "JSTypedArrays.h" -
trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp
r205324 r205462 30 30 #include "CallFrame.h" 31 31 #include "GetterSetter.h" 32 #include "JSC ellInlines.h"32 #include "JSCInlines.h" 33 33 #include "JSFunction.h" 34 34 #include "JSGenericTypedArrayViewPrototypeFunctions.h" -
trunk/Source/JavaScriptCore/runtime/JSWeakMap.cpp
r205131 r205462 27 27 #include "JSWeakMap.h" 28 28 29 #include "JSCJSValueInlines.h" 30 #include "SlotVisitorInlines.h" 31 #include "StructureInlines.h" 29 #include "JSCInlines.h" 32 30 #include "WeakMapData.h" 33 #include "WriteBarrierInlines.h"34 31 35 32 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/JSWeakSet.cpp
r205131 r205462 27 27 #include "JSWeakSet.h" 28 28 29 #include "JSCJSValueInlines.h" 30 #include "SlotVisitorInlines.h" 31 #include "StructureInlines.h" 29 #include "JSCInlines.h" 32 30 #include "WeakMapData.h" 33 #include "WriteBarrierInlines.h"34 31 35 32 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/MapConstructor.cpp
r205324 r205462 30 30 #include "GetterSetter.h" 31 31 #include "IteratorOperations.h" 32 #include "JSCJSValueInlines.h" 33 #include "JSCellInlines.h" 32 #include "JSCInlines.h" 34 33 #include "JSGlobalObject.h" 35 34 #include "JSMap.h" 36 35 #include "JSObjectInlines.h" 37 36 #include "MapPrototype.h" 38 #include "StructureInlines.h"39 37 40 38 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/MapIteratorPrototype.cpp
r205198 r205462 28 28 29 29 #include "IteratorOperations.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 32 31 #include "JSMapIterator.h" 33 #include "StructureInlines.h"34 32 35 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/MapPrototype.cpp
r205198 r205462 32 32 #include "GetterSetter.h" 33 33 #include "IteratorOperations.h" 34 #include "JSCJSValueInlines.h" 35 #include "JSFunctionInlines.h" 34 #include "JSCInlines.h" 36 35 #include "JSMap.h" 37 36 #include "JSMapIterator.h" 38 37 #include "Lookup.h" 39 38 #include "MapDataInlines.h" 40 #include "StructureInlines.h"41 39 42 40 #include "MapPrototype.lut.h" -
trunk/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
r204912 r205462 23 23 24 24 #include "ErrorInstance.h" 25 #include "Interpreter.h" 25 26 #include "JSFunction.h" 26 27 #include "JSString.h" -
trunk/Source/JavaScriptCore/runtime/NativeStdFunctionCell.cpp
r204912 r205462 27 27 #include "NativeStdFunctionCell.h" 28 28 29 #include "JSCJSValueInlines.h" 30 #include "JSCellInlines.h" 31 #include "JSFunctionInlines.h" 32 #include "SlotVisitorInlines.h" 29 #include "JSCInlines.h" 33 30 34 31 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/Operations.h
r205198 r205462 200 200 } 201 201 202 inline bool scribbleFreeCells() 203 { 204 return !ASSERT_DISABLED || Options::scribbleFreeCells(); 205 } 206 207 inline void scribble(void* base, size_t size) 208 { 209 for (size_t i = size / sizeof(EncodedJSValue); i--;) { 210 // Use a 16-byte aligned value to ensure that it passes the cell check. 211 static_cast<EncodedJSValue*>(base)[i] = JSValue::encode( 212 bitwise_cast<JSCell*>(static_cast<intptr_t>(0xbadbeef0))); 213 } 214 } 215 202 216 } // namespace JSC 203 217 -
trunk/Source/JavaScriptCore/runtime/Options.cpp
r204394 r205462 371 371 Options::useOSREntryToFTL() = false; 372 372 } 373 373 374 374 #if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000 375 375 // Override globally for now. Longer term we'll just make the default -
trunk/Source/JavaScriptCore/runtime/Options.h
r204912 r205462 183 183 v(bool, verboseSanitizeStack, false, Normal, nullptr) \ 184 184 v(bool, useGenerationalGC, true, Normal, nullptr) \ 185 v(bool, scribbleFreeCells, false, Normal, nullptr) \ 186 v(double, sizeClassProgression, 1.4, Normal, nullptr) \ 187 v(unsigned, largeAllocationCutoff, 100000, Normal, nullptr) \ 188 v(bool, dumpSizeClasses, false, Normal, nullptr) \ 189 v(bool, useBumpAllocator, true, Normal, nullptr) \ 185 190 v(bool, eagerlyUpdateTopCallFrame, false, Normal, nullptr) \ 186 191 \ -
trunk/Source/JavaScriptCore/runtime/PropertyTable.cpp
r204912 r205462 27 27 #include "PropertyMapHashTable.h" 28 28 29 #include "JSCJSValueInlines.h" 30 #include "JSCellInlines.h" 31 #include "SlotVisitorInlines.h" 32 #include "StructureInlines.h" 29 #include "JSCInlines.h" 33 30 34 31 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/ProxyConstructor.cpp
r205198 r205462 29 29 #include "Error.h" 30 30 #include "IdentifierInlines.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 31 #include "JSCInlines.h" 33 32 #include "ObjectConstructor.h" 34 33 #include "ObjectPrototype.h" -
trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp
r205198 r205462 30 30 #include "Error.h" 31 31 #include "IdentifierInlines.h" 32 #include "JSCJSValueInlines.h" 33 #include "JSCellInlines.h" 32 #include "JSCInlines.h" 34 33 #include "JSObjectInlines.h" 35 34 #include "ObjectConstructor.h" -
trunk/Source/JavaScriptCore/runtime/ProxyRevoke.cpp
r204912 r205462 27 27 #include "ProxyRevoke.h" 28 28 29 #include "JSC JSValueInlines.h"29 #include "JSCInlines.h" 30 30 #include "ProxyObject.h" 31 #include "SlotVisitorInlines.h"32 #include "StructureInlines.h"33 31 34 32 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/RegExp.cpp
r204912 r205462 297 297 } 298 298 299 int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int , 32>& ovector)299 int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int>& ovector) 300 300 { 301 301 return matchInline(vm, s, startOffset, ovector); … … 303 303 304 304 bool RegExp::matchConcurrently( 305 VM& vm, const String& s, unsigned startOffset, int& position, Vector<int , 32>& ovector)305 VM& vm, const String& s, unsigned startOffset, int& position, Vector<int>& ovector) 306 306 { 307 307 ConcurrentJITLocker locker(m_lock); … … 383 383 { 384 384 int offsetVectorSize = (m_numSubpatterns + 1) * 2; 385 Vector<int , 32> interpreterOvector;385 Vector<int> interpreterOvector; 386 386 interpreterOvector.resize(offsetVectorSize); 387 387 int* interpreterOffsetVector = interpreterOvector.data(); -
trunk/Source/JavaScriptCore/runtime/RegExp.h
r204912 r205462 65 65 const char* errorMessage() const { return m_constructionError; } 66 66 67 JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int , 32>& ovector);67 JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int>& ovector); 68 68 69 69 // Returns false if we couldn't run the regular expression for any reason. 70 bool matchConcurrently(VM&, const String&, unsigned startOffset, int& position, Vector<int , 32>& ovector);70 bool matchConcurrently(VM&, const String&, unsigned startOffset, int& position, Vector<int>& ovector); 71 71 72 72 JS_EXPORT_PRIVATE MatchResult match(VM&, const String&, unsigned startOffset); … … 75 75 76 76 // Call these versions of the match functions if you're desperate for performance. 77 int matchInline(VM&, const String&, unsigned startOffset, Vector<int, 32>& ovector); 77 template<typename VectorType> 78 int matchInline(VM&, const String&, unsigned startOffset, VectorType& ovector); 78 79 MatchResult matchInline(VM&, const String&, unsigned startOffset); 79 80 -
trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h
r204912 r205462 81 81 RegExpCachedResult m_cachedResult; 82 82 bool m_multiline; 83 Vector<int , 32> m_ovector;83 Vector<int> m_ovector; 84 84 }; 85 85 -
trunk/Source/JavaScriptCore/runtime/RegExpInlines.h
r204912 r205462 95 95 } 96 96 97 ALWAYS_INLINE int RegExp::matchInline(VM& vm, const String& s, unsigned startOffset, Vector<int, 32>& ovector) 97 template<typename VectorType> 98 ALWAYS_INLINE int RegExp::matchInline(VM& vm, const String& s, unsigned startOffset, VectorType& ovector) 98 99 { 99 100 #if ENABLE(REGEXP_TRACING) -
trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
r204912 r205462 35 35 ALWAYS_INLINE JSArray* tryCreateUninitializedRegExpMatchesArray(VM& vm, Structure* structure, unsigned initialLength) 36 36 { 37 unsigned vectorLength = std::max(BASE_VECTOR_LEN, initialLength);37 unsigned vectorLength = initialLength; 38 38 if (vectorLength > MAX_STORAGE_VECTOR_LENGTH) 39 39 return 0; 40 40 41 void* temp ;42 if (! vm.heap.tryAllocateStorage(0, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)), &temp))43 return 0;41 void* temp = vm.heap.tryAllocateAuxiliary(nullptr, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue))); 42 if (!temp) 43 return nullptr; 44 44 Butterfly* butterfly = Butterfly::fromBase(temp, 0, structure->outOfLineCapacity()); 45 45 butterfly->setVectorLength(vectorLength); 46 46 butterfly->setPublicLength(initialLength); 47 47 48 for (unsigned i = initialLength; i < vectorLength; ++i) 49 butterfly->contiguous()[i].clear(); 50 48 51 return JSArray::createWithButterfly(vm, structure, butterfly); 49 52 } … … 68 71 // https://bugs.webkit.org/show_bug.cgi?id=155144 69 72 73 auto setProperties = [&] () { 74 array->putDirect(vm, RegExpMatchesArrayIndexPropertyOffset, jsNumber(result.start)); 75 array->putDirect(vm, RegExpMatchesArrayInputPropertyOffset, input); 76 }; 77 78 unsigned numSubpatterns = regExp->numSubpatterns(); 79 70 80 if (UNLIKELY(globalObject->isHavingABadTime())) { 71 array = JSArray::tryCreateUninitialized(vm, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1); 81 array = JSArray::tryCreateUninitialized(vm, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1); 82 83 setProperties(); 84 85 array->initializeIndex(vm, 0, jsUndefined()); 86 87 for (unsigned i = 1; i <= numSubpatterns; ++i) 88 array->initializeIndex(vm, i, jsUndefined()); 89 90 // Now the object is safe to scan by GC. 72 91 73 92 array->initializeIndex(vm, 0, jsSubstringOfResolved(vm, input, result.start, result.end - result.start)); 74 93 75 if (unsigned numSubpatterns = regExp->numSubpatterns()) { 76 for (unsigned i = 1; i <= numSubpatterns; ++i) { 77 int start = subpatternResults[2 * i]; 78 if (start >= 0) 79 array->initializeIndex(vm, i, JSRopeString::createSubstringOfResolved(vm, input, start, subpatternResults[2 * i + 1] - start)); 80 else 81 array->initializeIndex(vm, i, jsUndefined()); 82 } 94 for (unsigned i = 1; i <= numSubpatterns; ++i) { 95 int start = subpatternResults[2 * i]; 96 if (start >= 0) 97 array->initializeIndex(vm, i, JSRopeString::createSubstringOfResolved(vm, input, start, subpatternResults[2 * i + 1] - start)); 83 98 } 84 99 } else { 85 array = tryCreateUninitializedRegExpMatchesArray(vm, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns()+ 1);100 array = tryCreateUninitializedRegExpMatchesArray(vm, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1); 86 101 RELEASE_ASSERT(array); 87 102 103 setProperties(); 104 105 array->initializeIndex(vm, 0, jsUndefined(), ArrayWithContiguous); 106 107 for (unsigned i = 1; i <= numSubpatterns; ++i) 108 array->initializeIndex(vm, i, jsUndefined(), ArrayWithContiguous); 109 110 // Now the object is safe to scan by GC. 111 88 112 array->initializeIndex(vm, 0, jsSubstringOfResolved(vm, input, result.start, result.end - result.start), ArrayWithContiguous); 89 113 90 if (unsigned numSubpatterns = regExp->numSubpatterns()) { 91 for (unsigned i = 1; i <= numSubpatterns; ++i) { 92 int start = subpatternResults[2 * i]; 93 if (start >= 0) 94 array->initializeIndex(vm, i, JSRopeString::createSubstringOfResolved(vm, input, start, subpatternResults[2 * i + 1] - start), ArrayWithContiguous); 95 else 96 array->initializeIndex(vm, i, jsUndefined(), ArrayWithContiguous); 97 } 114 for (unsigned i = 1; i <= numSubpatterns; ++i) { 115 int start = subpatternResults[2 * i]; 116 if (start >= 0) 117 array->initializeIndex(vm, i, JSRopeString::createSubstringOfResolved(vm, input, start, subpatternResults[2 * i + 1] - start), ArrayWithContiguous); 98 118 } 99 119 } 100 101 array->putDirect(vm, RegExpMatchesArrayIndexPropertyOffset, jsNumber(result.start));102 array->putDirect(vm, RegExpMatchesArrayInputPropertyOffset, input);103 120 104 121 return array; -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
r205198 r205462 504 504 const ControlFunc& control, const PushFunc& push) 505 505 { 506 Vector<int> ovector; 507 506 508 while (matchPosition < inputSize) { 507 509 if (control() == AbortSplit) 508 510 return; 509 511 510 Vector<int, 32> ovector;511 512 ovector.resize(0); 513 512 514 // a. Perform ? Set(splitter, "lastIndex", q, true). 513 515 // b. Let z be ? RegExpExec(splitter, S). -
trunk/Source/JavaScriptCore/runtime/RuntimeType.cpp
r204912 r205462 29 29 #include "RuntimeType.h" 30 30 31 #include "JSCJSValue.h" 32 #include "JSCJSValueInlines.h" 31 #include "JSCInlines.h" 33 32 34 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp
r205324 r205462 34 34 #include "HeapInlines.h" 35 35 #include "HeapIterationScope.h" 36 #include "HeapUtil.h" 36 37 #include "InlineCallFrame.h" 37 38 #include "Interpreter.h" … … 358 359 359 360 TinyBloomFilter filter = m_vm.heap.objectSpace().blocks().filter(); 360 MarkedBlockSet& markedBlockSet = m_vm.heap.objectSpace().blocks();361 361 362 362 for (UnprocessedStackTrace& unprocessedStackTrace : m_unprocessedStackTraces) { … … 392 392 StackFrame& stackFrame = stackTrace.frames.last(); 393 393 bool alreadyHasExecutable = !!stackFrame.executable; 394 if (!Heap ::isValueGCObject(filter, markedBlockSet, callee)) {394 if (!HeapUtil::isValueGCObject(m_vm.heap, filter, callee)) { 395 395 if (!alreadyHasExecutable) 396 396 stackFrame.frameType = FrameType::Unknown; … … 437 437 } 438 438 439 RELEASE_ASSERT(Heap ::isPointerGCObject(filter, markedBlockSet, executable));439 RELEASE_ASSERT(HeapUtil::isPointerGCObjectJSCell(m_vm.heap, filter, executable)); 440 440 stackFrame.frameType = FrameType::Executable; 441 441 stackFrame.executable = executable; -
trunk/Source/JavaScriptCore/runtime/SetConstructor.cpp
r205324 r205462 30 30 #include "GetterSetter.h" 31 31 #include "IteratorOperations.h" 32 #include "JSCJSValueInlines.h" 33 #include "JSCellInlines.h" 32 #include "JSCInlines.h" 34 33 #include "JSGlobalObject.h" 35 34 #include "JSObjectInlines.h" … … 37 36 #include "MapData.h" 38 37 #include "SetPrototype.h" 39 #include "StructureInlines.h"40 38 41 39 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/SetIteratorPrototype.cpp
r205198 r205462 28 28 29 29 #include "IteratorOperations.h" 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 32 31 #include "JSSetIterator.h" 33 #include "StructureInlines.h"34 32 35 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/SetPrototype.cpp
r205198 r205462 32 32 #include "GetterSetter.h" 33 33 #include "IteratorOperations.h" 34 #include "JSCJSValueInlines.h" 35 #include "JSFunctionInlines.h" 34 #include "JSCInlines.h" 36 35 #include "JSSet.h" 37 36 #include "JSSetIterator.h" 38 37 #include "Lookup.h" 39 38 #include "MapDataInlines.h" 40 #include "StructureInlines.h"41 39 42 40 #include "SetPrototype.lut.h" -
trunk/Source/JavaScriptCore/runtime/StringConstructor.cpp
r205198 r205462 29 29 #include "JSCInlines.h" 30 30 #include "StringPrototype.h" 31 #include <wtf/text/StringBuilder.h> 31 32 32 33 namespace JSC { -
trunk/Source/JavaScriptCore/runtime/StringIteratorPrototype.cpp
r204912 r205462 28 28 #include "StringIteratorPrototype.h" 29 29 30 #include "JSCJSValueInlines.h" 31 #include "JSCellInlines.h" 30 #include "JSCInlines.h" 32 31 #include "JSGlobalObject.h" 33 32 #include "JSStringIterator.h" 34 33 #include "ObjectConstructor.h" 35 #include "StructureInlines.h"36 34 37 35 #include "StringIteratorPrototype.lut.h" -
trunk/Source/JavaScriptCore/runtime/StructureInlines.h
r202588 r205462 243 243 ALWAYS_INLINE WriteBarrier<PropertyTable>& Structure::propertyTable() 244 244 { 245 ASSERT(!globalObject() || (!globalObject()->vm().heap.isCollecting() || globalObject()->vm().heap.isHeapSnapshotting()));246 245 return m_propertyTableUnsafe; 247 246 } -
trunk/Source/JavaScriptCore/runtime/TemplateRegistry.cpp
r204912 r205462 27 27 #include "TemplateRegistry.h" 28 28 29 #include "JSC JSValueInlines.h"29 #include "JSCInlines.h" 30 30 #include "JSGlobalObject.h" 31 31 #include "ObjectConstructor.h" 32 #include "StructureInlines.h"33 32 #include "WeakGCMapInlines.h" 34 33 -
trunk/Source/JavaScriptCore/runtime/TestRunnerUtils.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2013 , 2014Apple Inc. All rights reserved.2 * Copyright (C) 2013-2014, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 29 29 #include "CodeBlock.h" 30 #include "HeapStatistics.h" 30 31 #include "JSCInlines.h" 32 #include "LLIntData.h" 31 33 32 34 namespace JSC { … … 151 153 } 152 154 155 // This is a hook called at the bitter end of some of our tests. 156 void finalizeStatsAtEndOfTesting() 157 { 158 if (Options::logHeapStatisticsAtExit()) 159 HeapStatistics::reportSuccess(); 160 if (Options::reportLLIntStats()) 161 LLInt::Data::finalizeStats(); 162 } 163 153 164 } // namespace JSC 154 165 -
trunk/Source/JavaScriptCore/runtime/TestRunnerUtils.h
r204912 r205462 54 54 JS_EXPORT_PRIVATE unsigned numberOfOSRExitFuzzChecks(); 55 55 56 JS_EXPORT_PRIVATE void finalizeStatsAtEndOfTesting(); 57 56 58 } // namespace JSC 57 59 -
trunk/Source/JavaScriptCore/runtime/ThrowScope.cpp
r205198 r205462 27 27 #include "ThrowScope.h" 28 28 29 #include "JSC JSValueInlines.h"29 #include "JSCInlines.h" 30 30 #include "VM.h" 31 31 -
trunk/Source/JavaScriptCore/runtime/TypeProfilerLog.cpp
r204912 r205462 30 30 #include "TypeProfilerLog.h" 31 31 32 #include "JSC JSValueInlines.h"32 #include "JSCInlines.h" 33 33 #include "TypeLocation.h" 34 34 #include <wtf/CurrentTime.h> -
trunk/Source/JavaScriptCore/runtime/TypeSet.cpp
r204912 r205462 28 28 29 29 #include "InspectorProtocolObjects.h" 30 #include "JSCJSValue.h" 31 #include "JSCJSValueInlines.h" 30 #include "JSCInlines.h" 32 31 #include <wtf/text/CString.h> 33 32 #include <wtf/text/WTFString.h> -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r204994 r205462 70 70 #include "JSTemplateRegistryKey.h" 71 71 #include "JSWithScope.h" 72 #include "LLIntData.h" 72 73 #include "Lexer.h" 73 74 #include "Lookup.h" … … 99 100 #include <wtf/CurrentTime.h> 100 101 #include <wtf/ProcessID.h> 102 #include <wtf/SimpleStats.h> 101 103 #include <wtf/StringPrintStream.h> 102 104 #include <wtf/Threading.h> … … 107 109 #if !ENABLE(JIT) 108 110 #include "CLoopStack.h" 111 #include "CLoopStackInlines.h" 109 112 #endif 110 113 … … 163 166 , propertyNames(nullptr) 164 167 , emptyList(new MarkedArgumentBuffer) 168 , machineCodeBytesPerBytecodeWordForBaselineJIT(std::make_unique<SimpleStats>()) 165 169 , customGetterSetterFunctionMap(*this) 166 170 , stringCache(*this) … … 874 878 } 875 879 880 #if !ENABLE(JIT) 881 bool VM::ensureStackCapacityForCLoop(Register* newTopOfStack) 882 { 883 return interpreter->cloopStack().ensureCapacityFor(newTopOfStack); 884 } 885 886 bool VM::isSafeToRecurseSoftCLoop() const 887 { 888 return interpreter->cloopStack().isSafeToRecurse(); 889 } 890 #endif // !ENABLE(JIT) 891 876 892 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/VM.h
r205198 r205462 40 40 #include "JSCJSValue.h" 41 41 #include "JSLock.h" 42 #include "LLIntData.h"43 42 #include "MacroAssemblerCodeRef.h" 44 43 #include "Microtask.h" … … 61 60 #include <wtf/HashMap.h> 62 61 #include <wtf/HashSet.h> 63 #include <wtf/SimpleStats.h>64 62 #include <wtf/StackBounds.h> 65 63 #include <wtf/Stopwatch.h> … … 72 70 #include <wtf/ListHashSet.h> 73 71 #endif 72 73 namespace WTF { 74 class SimpleStats; 75 } // namespace WTF 76 using WTF::SimpleStats; 74 77 75 78 namespace JSC { … … 343 346 NumericStrings numericStrings; 344 347 DateInstanceCache dateInstanceCache; 345 WTF::SimpleStatsmachineCodeBytesPerBytecodeWordForBaselineJIT;348 std::unique_ptr<SimpleStats> machineCodeBytesPerBytecodeWordForBaselineJIT; 346 349 WeakGCMap<std::pair<CustomGetterSetter*, int>, JSCustomGetterSetterFunction> customGetterSetterFunctionMap; 347 350 WeakGCMap<StringImpl*, JSString, PtrHash<StringImpl*>> stringCache; … … 642 645 m_lastException = exception; 643 646 } 647 648 #if !ENABLE(JIT) 649 bool ensureStackCapacityForCLoop(Register* newTopOfStack); 650 bool isSafeToRecurseSoftCLoop() const; 651 #endif // !ENABLE(JIT) 644 652 645 653 JS_EXPORT_PRIVATE void throwException(ExecState*, Exception*); -
trunk/Source/JavaScriptCore/runtime/VMEntryScope.h
r205198 r205462 27 27 #define VMEntryScope_h 28 28 29 #include "Interpreter.h"30 29 #include <wtf/StackBounds.h> 31 30 #include <wtf/StackStats.h> -
trunk/Source/JavaScriptCore/runtime/VMInlines.h
r204912 r205462 31 31 #include "Watchdog.h" 32 32 33 #if !ENABLE(JIT)34 #include "CLoopStackInlines.h"35 #endif36 37 33 namespace JSC { 38 34 … … 43 39 return newTopOfStack >= m_softStackLimit; 44 40 #else 45 return interpreter->cloopStack().ensureCapacityFor(newTopOfStack);41 return ensureStackCapacityForCLoop(newTopOfStack); 46 42 #endif 47 43 … … 52 48 bool safe = isSafeToRecurse(m_softStackLimit); 53 49 #if !ENABLE(JIT) 54 safe = safe && i nterpreter->cloopStack().isSafeToRecurse();50 safe = safe && isSafeToRecurseSoftCLoop(); 55 51 #endif 56 52 return safe; -
trunk/Source/JavaScriptCore/runtime/WeakMapConstructor.cpp
r205324 r205462 1 1 /* 2 * Copyright (C) 2013 Apple, Inc. All rights reserved.2 * Copyright (C) 2013, 2016 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "Error.h" 30 30 #include "IteratorOperations.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 31 #include "JSCInlines.h" 33 32 #include "JSGlobalObject.h" 34 33 #include "JSObjectInlines.h" 35 34 #include "JSWeakMap.h" 36 #include "StructureInlines.h"37 35 #include "WeakMapPrototype.h" 38 36 -
trunk/Source/JavaScriptCore/runtime/WeakMapData.cpp
r204912 r205462 30 30 #include "CopyVisitorInlines.h" 31 31 #include "ExceptionHelpers.h" 32 #include "JSCJSValueInlines.h" 33 #include "SlotVisitorInlines.h" 32 #include "JSCInlines.h" 34 33 35 34 #include <wtf/MathExtras.h> -
trunk/Source/JavaScriptCore/runtime/WeakMapPrototype.cpp
r205198 r205462 27 27 #include "WeakMapPrototype.h" 28 28 29 #include "JSC JSValueInlines.h"29 #include "JSCInlines.h" 30 30 #include "JSWeakMap.h" 31 #include "StructureInlines.h"32 31 #include "WeakMapData.h" 33 32 -
trunk/Source/JavaScriptCore/runtime/WeakSetConstructor.cpp
r205324 r205462 1 1 /* 2 * Copyright (C) 2015 Apple, Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple, Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #include "Error.h" 30 30 #include "IteratorOperations.h" 31 #include "JSCJSValueInlines.h" 32 #include "JSCellInlines.h" 31 #include "JSCInlines.h" 33 32 #include "JSGlobalObject.h" 34 33 #include "JSObjectInlines.h" 35 34 #include "JSWeakSet.h" 36 #include "StructureInlines.h"37 35 #include "WeakSetPrototype.h" 38 36 -
trunk/Source/JavaScriptCore/runtime/WeakSetPrototype.cpp
r205198 r205462 27 27 #include "WeakSetPrototype.h" 28 28 29 #include "JSC JSValueInlines.h"29 #include "JSCInlines.h" 30 30 #include "JSWeakSet.h" 31 #include "StructureInlines.h"32 31 #include "WeakMapData.h" 33 32 -
trunk/Source/JavaScriptCore/testRegExp.cpp
r204912 r205462 192 192 { 193 193 bool result = true; 194 Vector<int , 32> outVector;194 Vector<int> outVector; 195 195 outVector.resize(regExpTest->expectVector.size()); 196 196 int matchResult = regexp->match(vm, regExpTest->subject, regExpTest->offset, outVector); -
trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp
r204912 r205462 27 27 #include "JSDollarVM.h" 28 28 29 #include "JSCJSValueInlines.h" 30 #include "StructureInlines.h" 29 #include "JSCInlines.h" 31 30 32 31 namespace JSC { -
trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp
r204912 r205462 147 147 { 148 148 MarkedBlock* candidate = MarkedBlock::blockFor(ptr); 149 return heap->objectSpace().blocks().set().contains(candidate); 149 if (heap->objectSpace().blocks().set().contains(candidate)) 150 return true; 151 for (LargeAllocation* allocation : heap->objectSpace().largeAllocations()) { 152 if (allocation->contains(ptr)) 153 return true; 154 } 155 return false; 150 156 } 151 157 -
trunk/Source/WTF/ChangeLog
r205362 r205462 1 2016-08-31 Filip Pizlo <fpizlo@apple.com> 2 3 Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression 4 https://bugs.webkit.org/show_bug.cgi?id=160125 5 6 Reviewed by Geoffrey Garen and Keith Miller. 7 8 I needed tryFastAlignedMalloc() so I added it. 9 10 * wtf/FastMalloc.cpp: 11 (WTF::tryFastAlignedMalloc): 12 * wtf/FastMalloc.h: 13 * wtf/ParkingLot.cpp: 14 (WTF::ParkingLot::forEachImpl): 15 (WTF::ParkingLot::forEach): Deleted. 16 * wtf/ParkingLot.h: 17 (WTF::ParkingLot::parkConditionally): 18 (WTF::ParkingLot::unparkOne): 19 (WTF::ParkingLot::forEach): 20 * wtf/ScopedLambda.h: 21 (WTF::scopedLambdaRef): 22 * wtf/SentinelLinkedList.h: 23 (WTF::SentinelLinkedList::forEach): 24 (WTF::RawNode>::takeFrom): 25 * wtf/SimpleStats.h: 26 (WTF::SimpleStats::operator bool): 27 (WTF::SimpleStats::operator!): Deleted. 28 1 29 2016-09-02 JF Bastien <jfbastien@apple.com> 2 30 -
trunk/Source/WTF/wtf/FastMalloc.cpp
r204917 r205462 1 // Copyright (c) 2005, 2007, Google Inc. All rights reserved.2 3 1 /* 4 * Copyright (C) 2005-2009, 2011, 2015 Apple Inc. All rights reserved. 2 * Copyright (c) 2005, 2007, Google Inc. All rights reserved. 3 * Copyright (C) 2005-2009, 2011, 2015-2016 Apple Inc. All rights reserved. 5 4 * Redistribution and use in source and binary forms, with or without 6 5 * modification, are permitted provided that the following conditions … … 103 102 } 104 103 104 void* tryFastAlignedMalloc(size_t alignment, size_t size) 105 { 106 return _aligned_malloc(size, alignment); 107 } 108 105 109 void fastAlignedFree(void* p) 106 110 { … … 111 115 112 116 void* fastAlignedMalloc(size_t alignment, size_t size) 117 { 118 void* p = nullptr; 119 posix_memalign(&p, alignment, size); 120 return p; 121 } 122 123 void* tryFastAlignedMalloc(size_t alignment, size_t size) 113 124 { 114 125 void* p = nullptr; … … 242 253 } 243 254 255 void* tryFastAlignedMalloc(size_t alignment, size_t size) 256 { 257 return bmalloc::api::tryMemalign(alignment, size); 258 } 259 244 260 void fastAlignedFree(void* p) 245 261 { -
trunk/Source/WTF/wtf/FastMalloc.h
r204917 r205462 1 1 /* 2 * Copyright (C) 2005-2009, 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2005-2009, 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 56 56 // Allocations from fastAlignedMalloc() must be freed using fastAlignedFree(). 57 57 WTF_EXPORT_PRIVATE void* fastAlignedMalloc(size_t alignment, size_t); 58 WTF_EXPORT_PRIVATE void* tryFastAlignedMalloc(size_t alignment, size_t); 58 59 WTF_EXPORT_PRIVATE void fastAlignedFree(void*); 59 60 … … 111 112 using WTF::fastStrDup; 112 113 using WTF::fastZeroedMalloc; 114 using WTF::tryFastAlignedMalloc; 113 115 using WTF::tryFastCalloc; 114 116 using WTF::tryFastMalloc; -
trunk/Source/WTF/wtf/ParkingLot.cpp
r204912 r205462 768 768 } 769 769 770 NEVER_INLINE void ParkingLot::forEach (std::function<void(ThreadIdentifier, const void*)>callback)770 NEVER_INLINE void ParkingLot::forEachImpl(const ScopedLambda<void(ThreadIdentifier, const void*)>& callback) 771 771 { 772 772 Vector<Bucket*> bucketsToUnlock = lockHashtable(); -
trunk/Source/WTF/wtf/ParkingLot.h
r204912 r205462 67 67 static ParkResult parkConditionally( 68 68 const void* address, 69 ValidationFunctor&& validation,70 BeforeSleepFunctor&& beforeSleep,69 const ValidationFunctor& validation, 70 const BeforeSleepFunctor& beforeSleep, 71 71 Clock::time_point timeout) 72 72 { 73 73 return parkConditionallyImpl( 74 74 address, 75 scopedLambda <bool()>(std::forward<ValidationFunctor>(validation)),76 scopedLambda <void()>(std::forward<BeforeSleepFunctor>(beforeSleep)),75 scopedLambdaRef<bool()>(validation), 76 scopedLambdaRef<void()>(beforeSleep), 77 77 timeout); 78 78 } … … 125 125 // WTF::Lock uses the timeToBeFair and token mechanism to implement eventual fairness. 126 126 template<typename Callback> 127 static void unparkOne(const void* address, Callback&& callback)127 static void unparkOne(const void* address, const Callback& callback) 128 128 { 129 unparkOneImpl(address, scopedLambda <intptr_t(UnparkResult)>(std::forward<Callback>(callback)));129 unparkOneImpl(address, scopedLambdaRef<intptr_t(UnparkResult)>(callback)); 130 130 } 131 131 … … 146 146 // otherwise unconstrained. This method is useful primarily for debugging. It's also used by unit 147 147 // tests. 148 WTF_EXPORT_PRIVATE static void forEach(std::function<void(ThreadIdentifier, const void*)>); 148 template<typename Func> 149 static void forEach(const Func& func) 150 { 151 forEachImpl(scopedLambdaRef<void(ThreadIdentifier, const void*)>(func)); 152 } 149 153 150 154 private: … … 158 162 const void* address, const ScopedLambda<intptr_t(UnparkResult)>& callback); 159 163 160 WTF_EXPORT_PRIVATE static void forEachImpl(const std::function<void(ThreadIdentifier, const void*)>&);164 WTF_EXPORT_PRIVATE static void forEachImpl(const ScopedLambda<void(ThreadIdentifier, const void*)>&); 161 165 }; 162 166 -
trunk/Source/WTF/wtf/ScopedLambda.h
r204912 r205462 127 127 } 128 128 129 template<typename FunctionType, typename Functor> class ScopedLambdaRefFunctor; 130 template<typename ResultType, typename... ArgumentTypes, typename Functor> 131 class ScopedLambdaRefFunctor<ResultType (ArgumentTypes...), Functor> : public ScopedLambda<ResultType (ArgumentTypes...)> { 132 public: 133 ScopedLambdaRefFunctor(const Functor& functor) 134 : ScopedLambda<ResultType (ArgumentTypes...)>(implFunction, this) 135 , m_functor(&functor) 136 { 137 } 138 139 // We need to make sure that copying and moving ScopedLambdaRefFunctor results in a 140 // ScopedLambdaRefFunctor whose ScopedLambda supertype still points to this rather than 141 // other. 142 ScopedLambdaRefFunctor(const ScopedLambdaRefFunctor& other) 143 : ScopedLambda<ResultType (ArgumentTypes...)>(implFunction, this) 144 , m_functor(other.m_functor) 145 { 146 } 147 148 ScopedLambdaRefFunctor(ScopedLambdaRefFunctor&& other) 149 : ScopedLambda<ResultType (ArgumentTypes...)>(implFunction, this) 150 , m_functor(other.m_functor) 151 { 152 } 153 154 ScopedLambdaRefFunctor& operator=(const ScopedLambdaRefFunctor& other) 155 { 156 m_functor = other.m_functor; 157 return *this; 158 } 159 160 ScopedLambdaRefFunctor& operator=(ScopedLambdaRefFunctor&& other) 161 { 162 m_functor = other.m_functor; 163 return *this; 164 } 165 166 private: 167 static ResultType implFunction(void* argument, ArgumentTypes... arguments) 168 { 169 return (*static_cast<ScopedLambdaRefFunctor*>(argument)->m_functor)(arguments...); 170 } 171 172 const Functor* m_functor; 173 }; 174 175 // This is for when you already refer to a functor by reference, and you know its lifetime is 176 // good. This just creates a ScopedLambda that points to your functor. 177 template<typename FunctionType, typename Functor> 178 ScopedLambdaRefFunctor<FunctionType, Functor> scopedLambdaRef(const Functor& functor) 179 { 180 return ScopedLambdaRefFunctor<FunctionType, Functor>(functor); 181 } 182 129 183 } // namespace WTF 130 184 131 185 using WTF::ScopedLambda; 132 186 using WTF::scopedLambda; 187 using WTF::scopedLambdaRef; 133 188 134 189 #endif // ScopedLambda_h -
trunk/Source/WTF/wtf/SentinelLinkedList.h
r195585 r205462 102 102 103 103 bool isEmpty() { return begin() == end(); } 104 104 105 template<typename Func> 106 void forEach(const Func& func) 107 { 108 for (iterator iter = begin(); iter != end();) { 109 iterator next = iter->next(); 110 func(iter); 111 iter = next; 112 } 113 } 114 115 void takeFrom(SentinelLinkedList<T, RawNode>&); 116 105 117 private: 106 118 RawNode m_headSentinel; … … 245 257 } 246 258 259 template <typename T, typename RawNode> 260 inline void SentinelLinkedList<T, RawNode>::takeFrom(SentinelLinkedList<T, RawNode>& other) 261 { 262 if (other.isEmpty()) 263 return; 264 265 m_tailSentinel.prev()->setNext(other.m_headSentinel.next()); 266 other.m_headSentinel.next()->setPrev(m_tailSentinel.prev()); 267 268 m_tailSentinel.setPrev(other.m_tailSentinel.prev()); 269 m_tailSentinel.prev()->setNext(&m_tailSentinel); 270 271 other.m_headSentinel.setNext(&other.m_tailSentinel); 272 other.m_tailSentinel.setPrev(&other.m_headSentinel); 273 } 274 247 275 } 248 276 -
trunk/Source/WTF/wtf/SimpleStats.h
r111778 r205462 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 50 50 } 51 51 52 bool operator!() const52 explicit operator bool() const 53 53 { 54 return ! m_count;54 return !!m_count; 55 55 } 56 56 … … 111 111 } // namespace WTF 112 112 113 using WTF::SimpleStats; 114 113 115 #endif // SimpleStats_h 114 116 -
trunk/Source/WebCore/ChangeLog
r205458 r205462 1 2016-08-31 Filip Pizlo <fpizlo@apple.com> 2 3 Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression 4 https://bugs.webkit.org/show_bug.cgi?id=160125 5 6 Reviewed by Geoffrey Garen and Keith Miller. 7 8 No new tests because no new WebCore behavior. 9 10 Just rewiring #includes. 11 12 * ForwardingHeaders/heap/HeapInlines.h: Added. 13 * ForwardingHeaders/interpreter/Interpreter.h: Removed. 14 * ForwardingHeaders/runtime/AuxiliaryBarrierInlines.h: Added. 15 * Modules/indexeddb/IDBCursorWithValue.cpp: 16 * Modules/indexeddb/client/TransactionOperation.cpp: 17 * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp: 18 * Modules/indexeddb/server/UniqueIDBDatabase.cpp: 19 * bindings/js/JSApplePayPaymentAuthorizedEventCustom.cpp: 20 * bindings/js/JSApplePayPaymentMethodSelectedEventCustom.cpp: 21 * bindings/js/JSApplePayShippingContactSelectedEventCustom.cpp: 22 * bindings/js/JSApplePayShippingMethodSelectedEventCustom.cpp: 23 * bindings/js/JSClientRectCustom.cpp: 24 * bindings/js/JSDOMBinding.cpp: 25 * bindings/js/JSDOMBinding.h: 26 * bindings/js/JSDeviceMotionEventCustom.cpp: 27 * bindings/js/JSDeviceOrientationEventCustom.cpp: 28 * bindings/js/JSErrorEventCustom.cpp: 29 * bindings/js/JSIDBCursorWithValueCustom.cpp: 30 * bindings/js/JSIDBIndexCustom.cpp: 31 * bindings/js/JSPopStateEventCustom.cpp: 32 * bindings/js/JSWebGL2RenderingContextCustom.cpp: 33 * bindings/js/JSWorkerGlobalScopeCustom.cpp: 34 * bindings/js/WorkerScriptController.cpp: 35 * contentextensions/ContentExtensionParser.cpp: 36 * dom/ErrorEvent.cpp: 37 * html/HTMLCanvasElement.cpp: 38 * html/MediaDocument.cpp: 39 * inspector/CommandLineAPIModule.cpp: 40 * loader/EmptyClients.cpp: 41 * page/CaptionUserPreferences.cpp: 42 * page/Frame.cpp: 43 * page/PageGroup.cpp: 44 * page/UserContentController.cpp: 45 * platform/mock/mediasource/MockBox.cpp: 46 * testing/GCObservation.cpp: 47 1 48 2016-09-05 Fujii Hironori <Hironori.Fujii@sony.com> 2 49 -
trunk/Source/WebCore/Modules/indexeddb/IDBCursorWithValue.cpp
r204912 r205462 29 29 #if ENABLE(INDEXED_DATABASE) 30 30 31 #include <heap/HeapInlines.h> 32 31 33 namespace WebCore { 32 34 -
trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp
r204912 r205462 30 30 31 31 #include "IDBCursor.h" 32 #include <heap/HeapInlines.h> 32 33 33 34 namespace WebCore { -
trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
r204912 r205462 46 46 #include "SQLiteTransaction.h" 47 47 #include "ThreadSafeDataBuffer.h" 48 #include <heap/HeapInlines.h> 48 49 #include <heap/StrongInlines.h> 50 #include <runtime/AuxiliaryBarrierInlines.h> 49 51 #include <runtime/JSCJSValueInlines.h> 50 52 #include <runtime/JSGlobalObject.h> -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
r204912 r205462 40 40 #include "SerializedScriptValue.h" 41 41 #include "UniqueIDBDatabaseConnection.h" 42 #include <heap/HeapInlines.h> 43 #include <runtime/AuxiliaryBarrierInlines.h> 42 44 #include <runtime/StructureInlines.h> 43 45 #include <wtf/MainThread.h> -
trunk/Source/WebCore/bindings/js/JSApplePayPaymentAuthorizedEventCustom.cpp
r204912 r205462 29 29 #if ENABLE(APPLE_PAY) 30 30 31 #include <heap/HeapInlines.h> 31 32 #include <runtime/JSCJSValueInlines.h> 32 33 -
trunk/Source/WebCore/bindings/js/JSApplePayPaymentMethodSelectedEventCustom.cpp
r204912 r205462 29 29 #if ENABLE(APPLE_PAY) 30 30 31 #include <heap/HeapInlines.h> 31 32 #include <runtime/JSCJSValueInlines.h> 32 33 -
trunk/Source/WebCore/bindings/js/JSApplePayShippingContactSelectedEventCustom.cpp
r204912 r205462 29 29 #if ENABLE(APPLE_PAY) 30 30 31 #include <heap/HeapInlines.h> 31 32 #include <runtime/JSCJSValueInlines.h> 32 33 -
trunk/Source/WebCore/bindings/js/JSApplePayShippingMethodSelectedEventCustom.cpp
r204912 r205462 29 29 #if ENABLE(APPLE_PAY) 30 30 31 #include <runtime/IdentifierInlines.h> 32 #include <runtime/JSCJSValueInlines.h> 31 #include <runtime/JSCInlines.h> 33 32 #include <runtime/ObjectConstructor.h> 34 #include < runtime/StructureInlines.h>33 #include <wtf/text/StringBuilder.h> 35 34 36 35 using namespace JSC; -
trunk/Source/WebCore/bindings/js/JSClientRectCustom.cpp
r204912 r205462 29 29 #include "ClientRect.h" 30 30 #include <bytecode/CodeBlock.h> 31 #include <heap/HeapInlines.h> 32 #include <runtime/AuxiliaryBarrierInlines.h> 31 33 #include <runtime/IdentifierInlines.h> 32 34 #include <runtime/JSObject.h> -
trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp
r205198 r205462 39 39 #include <inspector/ScriptCallStack.h> 40 40 #include <inspector/ScriptCallStackFactory.h> 41 #include <interpreter/Interpreter.h>42 41 #include <runtime/DateInstance.h> 43 42 #include <runtime/Error.h> … … 50 49 #include <wtf/MathExtras.h> 51 50 #include <wtf/unicode/CharacterNames.h> 51 #include <wtf/text/StringBuilder.h> 52 52 53 53 using namespace JSC; -
trunk/Source/WebCore/bindings/js/JSDOMBinding.h
r205422 r205462 31 31 #include "WebCoreTypedArrayController.h" 32 32 #include <cstddef> 33 #include <heap/HeapInlines.h> 33 34 #include <heap/SlotVisitorInlines.h> 34 35 #include <heap/Weak.h> 35 36 #include <heap/WeakInlines.h> 37 #include <runtime/AuxiliaryBarrierInlines.h> 36 38 #include <runtime/Error.h> 37 39 #include <runtime/IteratorOperations.h> -
trunk/Source/WebCore/bindings/js/JSDeviceMotionEventCustom.cpp
r204912 r205462 32 32 #include "DeviceMotionData.h" 33 33 #include "DeviceMotionEvent.h" 34 #include <heap/HeapInlines.h> 35 #include <runtime/AuxiliaryBarrierInlines.h> 34 36 #include <runtime/IdentifierInlines.h> 35 37 #include <runtime/JSCJSValueInlines.h> -
trunk/Source/WebCore/bindings/js/JSDeviceOrientationEventCustom.cpp
r204912 r205462 32 32 #include "DeviceOrientationData.h" 33 33 #include "DeviceOrientationEvent.h" 34 #include <heap/HeapInlines.h> 34 35 #include <runtime/JSCJSValueInlines.h> 35 36 #include <runtime/StructureInlines.h> -
trunk/Source/WebCore/bindings/js/JSErrorEventCustom.cpp
r204912 r205462 28 28 29 29 #include "ErrorEvent.h" 30 #include <heap/HeapInlines.h> 30 31 31 32 using namespace JSC; -
trunk/Source/WebCore/bindings/js/JSIDBCursorWithValueCustom.cpp
r204912 r205462 30 30 31 31 #include "IDBCursorWithValue.h" 32 #include <heap/HeapInlines.h> 32 33 33 34 using namespace JSC; -
trunk/Source/WebCore/bindings/js/JSIDBIndexCustom.cpp
r204912 r205462 30 30 31 31 #include "IDBIndex.h" 32 #include <heap/HeapInlines.h> 32 33 33 34 using namespace JSC; -
trunk/Source/WebCore/bindings/js/JSPerformanceTimingCustom.cpp
r205286 r205462 30 30 31 31 #include "DOMWrapperWorld.h" 32 #include <heap/HeapInlines.h> 33 #include <runtime/AuxiliaryBarrierInlines.h> 32 34 #include <runtime/IdentifierInlines.h> 33 35 #include <runtime/JSObject.h> -
trunk/Source/WebCore/bindings/js/JSPopStateEventCustom.cpp
r204912 r205462 34 34 #include "DOMWrapperWorld.h" 35 35 #include "JSHistory.h" 36 #include <heap/HeapInlines.h> 36 37 #include <runtime/JSCJSValueInlines.h> 37 38 -
trunk/Source/WebCore/bindings/js/JSWebGL2RenderingContextCustom.cpp
r205198 r205462 29 29 #include "JSWebGL2RenderingContext.h" 30 30 31 #include <heap/HeapInlines.h> 31 32 #include <runtime/Error.h> 32 33 #include "NotImplemented.h" -
trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp
r205198 r205462 42 42 #include "WorkerLocation.h" 43 43 #include "WorkerNavigator.h" 44 #include <interpreter/Interpreter.h>45 44 46 45 #if ENABLE(WEB_SOCKETS) -
trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp
r205198 r205462 40 40 #include <bindings/ScriptValue.h> 41 41 #include <heap/StrongInlines.h> 42 #include <interpreter/Interpreter.h>43 42 #include <runtime/Completion.h> 44 43 #include <runtime/Error.h> -
trunk/Source/WebCore/contentextensions/ContentExtensionParser.cpp
r205324 r205462 36 36 #include "ContentExtensionsBackend.h" 37 37 #include "ContentExtensionsDebugging.h" 38 #include <JavaScriptCore/IdentifierInlines.h> 39 #include <JavaScriptCore/JSCJSValueInlines.h> 38 #include <JavaScriptCore/JSCInlines.h> 40 39 #include <JavaScriptCore/JSGlobalObject.h> 41 40 #include <JavaScriptCore/JSONObject.h> 42 #include <JavaScriptCore/JSObjectInlines.h>43 #include <JavaScriptCore/StructureInlines.h>44 41 #include <JavaScriptCore/VM.h> 45 42 #include <wtf/CurrentTime.h> -
trunk/Source/WebCore/dom/ErrorEvent.cpp
r204912 r205462 35 35 #include "DOMWrapperWorld.h" 36 36 #include "EventNames.h" 37 #include <heap/HeapInlines.h> 37 38 38 39 using namespace JSC; -
trunk/Source/WebCore/html/HTMLCanvasElement.cpp
r205053 r205462 52 52 #include <runtime/JSLock.h> 53 53 #include <wtf/RAMSize.h> 54 #include <wtf/text/StringBuilder.h> 54 55 55 56 #if ENABLE(WEBGL) -
trunk/Source/WebCore/html/MediaDocument.cpp
r205249 r205462 49 49 #include "ShadowRoot.h" 50 50 #include "TypedElementDescendantIterator.h" 51 #include <wtf/text/StringBuilder.h> 51 52 52 53 namespace WebCore { -
trunk/Source/WebCore/inspector/CommandLineAPIModule.cpp
r204912 r205462 30 30 #include "JSDOMGlobalObject.h" 31 31 #include "WebInjectedScriptManager.h" 32 #include <heap/HeapInlines.h> 32 33 #include <inspector/InjectedScript.h> 33 34 -
trunk/Source/WebCore/loader/EmptyClients.cpp
r204912 r205462 49 49 #include "ThreadableWebSocketChannel.h" 50 50 #include "UserContentProvider.h" 51 #include <heap/HeapInlines.h> 51 52 #include <wtf/NeverDestroyed.h> 52 53 -
trunk/Source/WebCore/page/CaptionUserPreferences.cpp
r204912 r205462 39 39 #include "UserStyleSheet.h" 40 40 #include "UserStyleSheetTypes.h" 41 #include <heap/HeapInlines.h> 41 42 #include <runtime/JSCellInlines.h> 42 43 #include <runtime/StructureInlines.h> -
trunk/Source/WebCore/page/Frame.cpp
r204912 r205462 111 111 #include <wtf/RefCountedLeakCounter.h> 112 112 #include <wtf/StdLibExtras.h> 113 #include <wtf/text/StringBuilder.h> 113 114 #include <yarr/RegularExpression.h> 114 115 -
trunk/Source/WebCore/page/PageGroup.cpp
r204912 r205462 37 37 #include "Settings.h" 38 38 #include "StorageNamespace.h" 39 #include <heap/HeapInlines.h> 39 40 #include <runtime/StructureInlines.h> 40 41 #include <wtf/StdLibExtras.h> -
trunk/Source/WebCore/page/UserContentController.cpp
r204912 r205462 30 30 #include "UserScript.h" 31 31 #include "UserStyleSheet.h" 32 #include <heap/HeapInlines.h> 32 33 #include <runtime/JSCellInlines.h> 33 34 #include <runtime/StructureInlines.h> -
trunk/Source/WebCore/platform/mock/mediasource/MockBox.cpp
r204912 r205462 29 29 #if ENABLE(MEDIA_SOURCE) 30 30 31 #include <JavaScriptCore/HeapInlines.h> 31 32 #include <JavaScriptCore/JSCJSValueInlines.h> 32 33 #include <JavaScriptCore/TypedArrayInlines.h> -
trunk/Source/WebCore/testing/GCObservation.cpp
r204912 r205462 27 27 #include "GCObservation.h" 28 28 29 #include <heap/HeapInlines.h> 30 29 31 namespace WebCore { 30 32 -
trunk/Source/WebKit2/ChangeLog
r205460 r205462 1 2016-08-31 Filip Pizlo <fpizlo@apple.com> 2 3 Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression 4 https://bugs.webkit.org/show_bug.cgi?id=160125 5 6 Reviewed by Geoffrey Garen and Keith Miller. 7 8 Just rewiring some #includes. 9 10 * UIProcess/ViewGestureController.cpp: 11 * UIProcess/WebPageProxy.cpp: 12 * UIProcess/WebProcessPool.cpp: 13 * UIProcess/WebProcessProxy.cpp: 14 * WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp: 15 * WebProcess/Plugins/Netscape/JSNPObject.cpp: 16 1 17 2016-09-05 Michael Catanzaro <mcatanzaro@igalia.com> 2 18 -
trunk/Source/WebKit2/UIProcess/ViewGestureController.cpp
r204912 r205462 34 34 #import <wtf/MathExtras.h> 35 35 #import <wtf/NeverDestroyed.h> 36 #import <wtf/text/StringBuilder.h> 36 37 37 38 using namespace WebCore; -
trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp
r205412 r205462 126 126 #include <stdio.h> 127 127 #include <wtf/NeverDestroyed.h> 128 #include <wtf/text/StringBuilder.h> 128 129 #include <wtf/text/StringView.h> 129 130 -
trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp
r205275 r205462 76 76 #include <wtf/NeverDestroyed.h> 77 77 #include <wtf/RunLoop.h> 78 #include <wtf/text/StringBuilder.h> 78 79 79 80 #if ENABLE(BATTERY_STATUS) -
trunk/Source/WebKit2/UIProcess/WebProcessProxy.cpp
r205369 r205462 58 58 #include <wtf/RunLoop.h> 59 59 #include <wtf/text/CString.h> 60 #include <wtf/text/StringBuilder.h> 60 61 #include <wtf/text/WTFString.h> 61 62 -
trunk/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp
r204912 r205462 30 30 #include "WebImage.h" 31 31 #include <JavaScriptCore/APICast.h> 32 #include <JavaScriptCore/HeapInlines.h> 32 33 #include <WebCore/Document.h> 33 34 #include <WebCore/FloatRect.h> -
trunk/Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp
r205198 r205462 1 1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved.2 * Copyright (C) 2010, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 33 33 #include "NPRuntimeObjectMap.h" 34 34 #include "NPRuntimeUtilities.h" 35 #include <JavaScriptCore/AuxiliaryBarrierInlines.h> 35 36 #include <JavaScriptCore/Error.h> 36 37 #include <JavaScriptCore/IdentifierInlines.h> -
trunk/Source/bmalloc/ChangeLog
r205215 r205462 1 2016-08-31 Filip Pizlo <fpizlo@apple.com> 2 3 Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression 4 https://bugs.webkit.org/show_bug.cgi?id=160125 5 6 Reviewed by Geoffrey Garen and Keith Miller. 7 8 I needed to tryMemalign, so I added such a thing. 9 10 * bmalloc/Allocator.cpp: 11 (bmalloc::Allocator::allocate): 12 (bmalloc::Allocator::tryAllocate): 13 (bmalloc::Allocator::allocateImpl): 14 * bmalloc/Allocator.h: 15 * bmalloc/Cache.h: 16 (bmalloc::Cache::tryAllocate): 17 * bmalloc/bmalloc.h: 18 (bmalloc::api::tryMemalign): 19 1 20 2016-08-30 Yusuke Suzuki <utatane.tea@gmail.com> 2 21 -
trunk/Source/bmalloc/bmalloc/Allocator.cpp
r204912 r205462 1 1 /* 2 * Copyright (C) 2014 , 2015Apple Inc. All rights reserved.2 * Copyright (C) 2014-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 65 65 void* Allocator::allocate(size_t alignment, size_t size) 66 66 { 67 bool crashOnFailure = true; 68 return allocateImpl(alignment, size, crashOnFailure); 69 } 70 71 void* Allocator::tryAllocate(size_t alignment, size_t size) 72 { 73 bool crashOnFailure = false; 74 return allocateImpl(alignment, size, crashOnFailure); 75 } 76 77 void* Allocator::allocateImpl(size_t alignment, size_t size, bool crashOnFailure) 78 { 67 79 BASSERT(isPowerOfTwo(alignment)); 68 80 … … 81 93 82 94 std::lock_guard<StaticMutex> lock(PerProcess<Heap>::mutex()); 83 return PerProcess<Heap>::getFastCase()->allocateLarge(lock, alignment, size); 95 Heap* heap = PerProcess<Heap>::getFastCase(); 96 if (crashOnFailure) 97 return heap->allocateLarge(lock, alignment, size); 98 return heap->tryAllocateLarge(lock, alignment, size); 84 99 } 85 100 -
trunk/Source/bmalloc/bmalloc/Allocator.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 44 44 void* tryAllocate(size_t); 45 45 void* allocate(size_t); 46 void* tryAllocate(size_t alignment, size_t); 46 47 void* allocate(size_t alignment, size_t); 47 48 void* reallocate(void*, size_t); … … 50 51 51 52 private: 53 void* allocateImpl(size_t alignment, size_t, bool crashOnFailure); 54 52 55 bool allocateFastCase(size_t, void*&); 53 56 void* allocateSlowCase(size_t); -
trunk/Source/bmalloc/bmalloc/Cache.h
r204912 r205462 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 42 42 static void* tryAllocate(size_t); 43 43 static void* allocate(size_t); 44 static void* tryAllocate(size_t alignment, size_t); 44 45 static void* allocate(size_t alignment, size_t); 45 46 static void deallocate(void*); … … 80 81 } 81 82 83 inline void* Cache::tryAllocate(size_t alignment, size_t size) 84 { 85 Cache* cache = PerThread<Cache>::getFastCase(); 86 if (!cache) 87 return allocateSlowCaseNullCache(alignment, size); 88 return cache->allocator().tryAllocate(alignment, size); 89 } 90 82 91 inline void* Cache::allocate(size_t alignment, size_t size) 83 92 { -
trunk/Source/bmalloc/bmalloc/bmalloc.h
r204917 r205462 1 1 /* 2 * Copyright (C) 2014 , 2015Apple Inc. All rights reserved.2 * Copyright (C) 2014-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 44 44 } 45 45 46 // Returns null on failure. 47 inline void* tryMemalign(size_t alignment, size_t size) 48 { 49 return Cache::tryAllocate(alignment, size); 50 } 51 46 52 // Crashes on failure. 47 53 inline void* memalign(size_t alignment, size_t size) -
trunk/Tools/ChangeLog
r205461 r205462 1 2016-08-31 Filip Pizlo <fpizlo@apple.com> 2 3 Butterflies should be allocated in Auxiliary MarkedSpace instead of CopiedSpace and we should rewrite as much of the GC as needed to make this not a regression 4 https://bugs.webkit.org/show_bug.cgi?id=160125 5 6 Reviewed by Geoffrey Garen and Keith Miller. 7 8 * DumpRenderTree/TestRunner.cpp: 9 * DumpRenderTree/mac/DumpRenderTree.mm: 10 (DumpRenderTreeMain): 11 * Scripts/run-jsc-stress-tests: 12 * TestWebKitAPI/Tests/WTF/Vector.cpp: 13 (TestWebKitAPI::TEST): 14 1 15 2016-09-05 Michael Catanzaro <mcatanzaro@igalia.com> 2 16 -
trunk/Tools/DumpRenderTree/TestRunner.cpp
r204918 r205462 35 35 #include "WorkQueueItem.h" 36 36 #include <JavaScriptCore/APICast.h> 37 #include <JavaScriptCore/HeapInlines.h> 37 38 #include <JavaScriptCore/JSContextRef.h> 38 39 #include <JavaScriptCore/JSCTestRunnerUtils.h> -
trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm
r204945 r205462 57 57 #import "WorkQueueItem.h" 58 58 #import <CoreFoundation/CoreFoundation.h> 59 #import <JavaScriptCore/HeapStatistics.h> 60 #import <JavaScriptCore/LLIntData.h> 61 #import <JavaScriptCore/Options.h> 59 #import <JavaScriptCore/TestRunnerUtils.h> 62 60 #import <WebCore/LogInitialization.h> 63 61 #import <WebKit/DOMElement.h> … … 1430 1428 [WebCoreStatistics garbageCollectJavaScriptObjects]; 1431 1429 [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts 1432 if (JSC::Options::logHeapStatisticsAtExit()) 1433 JSC::HeapStatistics::reportSuccess(); 1434 if (JSC::Options::reportLLIntStats()) 1435 JSC::LLInt::Data::finalizeStats(); 1430 JSC::finalizeStatsAtEndOfTesting(); 1436 1431 [pool release]; 1437 1432 returningFromMain = true; -
trunk/Tools/Scripts/run-jsc-stress-tests
r205387 r205462 422 422 BASE_OPTIONS = ["--useFTLJIT=false", "--useFunctionDotArguments=true", "--maxPerThreadStackUsage=1572864"] 423 423 EAGER_OPTIONS = ["--thresholdForJITAfterWarmUp=10", "--thresholdForJITSoon=10", "--thresholdForOptimizeAfterWarmUp=20", "--thresholdForOptimizeAfterLongWarmUp=20", "--thresholdForOptimizeSoon=20", "--thresholdForFTLOptimizeAfterWarmUp=20", "--thresholdForFTLOptimizeSoon=20", "--maximumEvalCacheableSourceLength=150000", "--useEagerCodeBlockJettisonTiming=true"] 424 NO_CJIT_OPTIONS = ["--useConcurrentJIT=false", "--thresholdForJITAfterWarmUp=100" ]424 NO_CJIT_OPTIONS = ["--useConcurrentJIT=false", "--thresholdForJITAfterWarmUp=100", "--scribbleFreeCells=true"] 425 425 FTL_OPTIONS = ["--useFTLJIT=true"] 426 426
Note:
See TracChangeset
for help on using the changeset viewer.