Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (225724 => 225725)
--- trunk/Source/_javascript_Core/ChangeLog 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-12-09 19:48:04 UTC (rev 225725)
@@ -1,3 +1,47 @@
+2017-12-05 Filip Pizlo <fpi...@apple.com>
+
+ InferredType should not use UnconditionalFinalizer
+ https://bugs.webkit.org/show_bug.cgi?id=180456
+
+ Reviewed by Saam Barati.
+
+ This turns InferredStructure into a cell so that we can unconditionally finalize them without
+ having to add things to the UnconditionalFinalizer list. I'm removing all uses of
+ UnconditionalFinalizers and WeakReferenceHarvesters because the data structures used to manage
+ them are a top cause of lock contention in the parallel GC. Also, we don't need those data
+ structures if we use IsoSubspaces, subspace iteration, and marking constraints.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * heap/Heap.cpp:
+ (JSC::Heap::finalizeUnconditionalFinalizers):
+ * heap/Heap.h:
+ * runtime/InferredStructure.cpp: Added.
+ (JSC::InferredStructure::create):
+ (JSC::InferredStructure::destroy):
+ (JSC::InferredStructure::createStructure):
+ (JSC::InferredStructure::visitChildren):
+ (JSC::InferredStructure::finalizeUnconditionally):
+ (JSC::InferredStructure::InferredStructure):
+ (JSC::InferredStructure::finishCreation):
+ * runtime/InferredStructure.h: Added.
+ * runtime/InferredStructureWatchpoint.cpp: Added.
+ (JSC::InferredStructureWatchpoint::fireInternal):
+ * runtime/InferredStructureWatchpoint.h: Added.
+ * runtime/InferredType.cpp:
+ (JSC::InferredType::visitChildren):
+ (JSC::InferredType::willStoreValueSlow):
+ (JSC::InferredType::makeTopSlow):
+ (JSC::InferredType::set):
+ (JSC::InferredType::removeStructure):
+ (JSC::InferredType::InferredStructureWatchpoint::fireInternal): Deleted.
+ (JSC::InferredType::InferredStructureFinalizer::finalizeUnconditionally): Deleted.
+ (JSC::InferredType::InferredStructure::InferredStructure): Deleted.
+ * runtime/InferredType.h:
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ * runtime/VM.h:
+
2017-12-09 Konstantin Tokarev <annu...@yandex.ru>
[python] Replace print >> operator with print() function for python3 compatibility
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (225724 => 225725)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-12-09 19:48:04 UTC (rev 225725)
@@ -499,6 +499,8 @@
0FBE0F7516C1DB0B0082C5E8 /* DFGPredictionInjectionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F6E16C1DB010082C5E8 /* DFGPredictionInjectionPhase.h */; };
0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */; };
0FBF158D19B7A53100695DD0 /* DFGBlockSetInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */; };
+ 0FBF92B91FD76FFF00AC28A8 /* InferredStructure.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBF92B81FD76FFC00AC28A8 /* InferredStructure.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0FBF92BA1FD7700400AC28A8 /* InferredStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBF92B71FD76FFC00AC28A8 /* InferredStructureWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097681468A6EF00CF2442 /* DFGOSRExit.h */; };
0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC097A0146B28C700CF2442 /* DFGThunks.h */; };
0FC20CB61852E2C600C9E954 /* DFGStrengthReductionPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC20CB41852E2C600C9E954 /* DFGStrengthReductionPhase.h */; };
@@ -2599,6 +2601,10 @@
0FBE0F7016C1DB010082C5E8 /* DFGUnificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUnificationPhase.h; path = dfg/DFGUnificationPhase.h; sourceTree = "<group>"; };
0FBF158A19B7A53100695DD0 /* DFGBlockSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBlockSet.cpp; path = dfg/DFGBlockSet.cpp; sourceTree = "<group>"; };
0FBF158B19B7A53100695DD0 /* DFGBlockSetInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBlockSetInlines.h; path = dfg/DFGBlockSetInlines.h; sourceTree = "<group>"; };
+ 0FBF92B51FD76FFC00AC28A8 /* InferredStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InferredStructureWatchpoint.cpp; sourceTree = "<group>"; };
+ 0FBF92B61FD76FFC00AC28A8 /* InferredStructure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InferredStructure.cpp; sourceTree = "<group>"; };
+ 0FBF92B71FD76FFC00AC28A8 /* InferredStructureWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InferredStructureWatchpoint.h; sourceTree = "<group>"; };
+ 0FBF92B81FD76FFC00AC28A8 /* InferredStructure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InferredStructure.h; sourceTree = "<group>"; };
0FC097681468A6EF00CF2442 /* DFGOSRExit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExit.h; path = dfg/DFGOSRExit.h; sourceTree = "<group>"; };
0FC0977E1469EBC400CF2442 /* DFGCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCommon.h; path = dfg/DFGCommon.h; sourceTree = "<group>"; };
0FC0978E146A6F6300CF2442 /* DFGOSRExit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGOSRExit.cpp; path = dfg/DFGOSRExit.cpp; sourceTree = "<group>"; };
@@ -6474,6 +6480,10 @@
0FB7F38F15ED8E3800F167B2 /* IndexingType.h */,
14386A761DD6989C008652C4 /* IndirectEvalExecutable.cpp */,
14386A771DD6989C008652C4 /* IndirectEvalExecutable.h */,
+ 0FBF92B61FD76FFC00AC28A8 /* InferredStructure.cpp */,
+ 0FBF92B81FD76FFC00AC28A8 /* InferredStructure.h */,
+ 0FBF92B51FD76FFC00AC28A8 /* InferredStructureWatchpoint.cpp */,
+ 0FBF92B71FD76FFC00AC28A8 /* InferredStructureWatchpoint.h */,
0F0A75201B94BFA900110660 /* InferredType.cpp */,
0F0A75211B94BFA900110660 /* InferredType.h */,
0FFC920F1B94D4DF0071DD66 /* InferredTypeTable.cpp */,
@@ -6484,9 +6494,9 @@
E178633F0D9BEC0000D74E75 /* InitializeThreading.h */,
E35E035D1B7AB43E0073AD2A /* InspectorInstrumentationObject.cpp */,
E35E035E1B7AB43E0073AD2A /* InspectorInstrumentationObject.h */,
+ A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
A7A8AF2C17ADB5F3005AB174 /* Int16Array.h */,
A7A8AF2D17ADB5F3005AB174 /* Int32Array.h */,
- A7A8AF2B17ADB5F3005AB174 /* Int8Array.h */,
BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */,
BC11667A0E199C05008066DD /* InternalFunction.h */,
A1B9E2331B4E0D6700BC7FED /* IntlCollator.cpp */,
@@ -6585,9 +6595,9 @@
BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */,
BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */,
79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */,
+ 0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
0F2B66CA17B6B5AB00A7AE3F /* JSInt16Array.h */,
0F2B66CB17B6B5AB00A7AE3F /* JSInt32Array.h */,
- 0F2B66C917B6B5AB00A7AE3F /* JSInt8Array.h */,
E33F507E1B8429A400413856 /* JSInternalPromise.cpp */,
E33F507F1B8429A400413856 /* JSInternalPromise.h */,
E33F50761B84225700413856 /* JSInternalPromiseConstructor.cpp */,
@@ -6653,13 +6663,13 @@
3032175DF1AD47D8998B34E1 /* JSSourceCode.h */,
BC02E9B60E1842FA000F9297 /* JSString.cpp */,
F692A8620255597D01FF60F7 /* JSString.h */,
+ 0F7DF13D1E2AFC4B0095951B /* JSStringHeapCellType.cpp */,
+ 0F7DF13E1E2AFC4B0095951B /* JSStringHeapCellType.h */,
FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */,
70EC0EBC1AA0D7DA00B6AAFA /* JSStringIterator.cpp */,
70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */,
2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */,
2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */,
- 0F7DF13D1E2AFC4B0095951B /* JSStringHeapCellType.cpp */,
- 0F7DF13E1E2AFC4B0095951B /* JSStringHeapCellType.h */,
0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */,
0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */,
70ECA6001AFDBEA200449739 /* JSTemplateRegistryKey.cpp */,
@@ -6676,10 +6686,10 @@
53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */,
53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */,
6507D2970E871E4A00D7D896 /* JSTypeInfo.h */,
+ 0F2B66D217B6B5AB00A7AE3F /* JSUint8Array.h */,
+ 0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
0F2B66D417B6B5AB00A7AE3F /* JSUint16Array.h */,
0F2B66D517B6B5AB00A7AE3F /* JSUint32Array.h */,
- 0F2B66D217B6B5AB00A7AE3F /* JSUint8Array.h */,
- 0F2B66D317B6B5AB00A7AE3F /* JSUint8ClampedArray.h */,
A7CA3AE117DA41AE006538AF /* JSWeakMap.cpp */,
A7CA3AE217DA41AE006538AF /* JSWeakMap.h */,
709FB8611AE335C60039D069 /* JSWeakSet.cpp */,
@@ -6893,11 +6903,11 @@
0F2D4DE019832D91007D4B19 /* TypeProfilerLog.h */,
0F2D4DE319832D91007D4B19 /* TypeSet.cpp */,
0F2D4DE419832D91007D4B19 /* TypeSet.h */,
+ A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
+ A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
A7A8AF3217ADB5F3005AB174 /* Uint16Array.h */,
866739D113BFDE710023D87C /* Uint16WithFraction.h */,
A7A8AF3317ADB5F3005AB174 /* Uint32Array.h */,
- A7A8AF3017ADB5F3005AB174 /* Uint8Array.h */,
- A7A8AF3117ADB5F3005AB174 /* Uint8ClampedArray.h */,
0FE050231AA9095600D33B33 /* VarOffset.cpp */,
0FE050241AA9095600D33B33 /* VarOffset.h */,
E18E3A570DF9278C00D90B34 /* VM.cpp */,
@@ -8048,6 +8058,7 @@
53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */,
BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
+ 0FBF92BA1FD7700400AC28A8 /* InferredStructureWatchpoint.h in Headers */,
79A228361D35D71F00D8E067 /* ArithProfile.h in Headers */,
0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
@@ -8623,6 +8634,7 @@
0F2B66AD17B6B54500A7AE3F /* GCIncomingRefCountedInlines.h in Headers */,
0F2B66AE17B6B54500A7AE3F /* GCIncomingRefCountedSet.h in Headers */,
0F2B66AF17B6B54500A7AE3F /* GCIncomingRefCountedSetInlines.h in Headers */,
+ 0FBF92B91FD76FFF00AC28A8 /* InferredStructure.h in Headers */,
2AABCDE718EF294200002096 /* GCLogging.h in Headers */,
0F9715311EB28BEE00A1645D /* GCRequest.h in Headers */,
A54E8EB018BFFBBB00556D28 /* GCSegmentedArray.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (225724 => 225725)
--- trunk/Source/_javascript_Core/Sources.txt 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/Sources.txt 2017-12-09 19:48:04 UTC (rev 225725)
@@ -743,6 +743,8 @@
runtime/Identifier.cpp
runtime/IndexingType.cpp
runtime/IndirectEvalExecutable.cpp
+runtime/InferredStructure.cpp
+runtime/InferredStructureWatchpoint.cpp
runtime/InferredType.cpp
runtime/InferredTypeTable.cpp
runtime/InferredValue.cpp
Modified: trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h (225724 => 225725)
--- trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h 2017-12-09 19:48:04 UTC (rev 225725)
@@ -37,10 +37,6 @@
ALWAYS_INLINE GCDeferralContext::~GCDeferralContext()
{
- ASSERT(!DisallowGC::isInEffectOnCurrentThread());
-#if ENABLE(GC_VALIDATION)
- ASSERT(!m_heap.vm()->isInitializingObject());
-#endif
if (UNLIKELY(m_shouldGC))
m_heap.collectIfNecessaryOrDefer();
}
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (225724 => 225725)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2017-12-09 19:48:04 UTC (rev 225725)
@@ -40,6 +40,7 @@
#include "HeapSnapshot.h"
#include "HeapVerifier.h"
#include "IncrementalSweeper.h"
+#include "InferredStructure.h"
#include "Interpreter.h"
#include "JITStubRoutineSet.h"
#include "JITWorklist.h"
@@ -551,8 +552,19 @@
}
}
+template<typename CellType>
+void Heap::finalizeUnconditionalFinalizers(Subspace& subspace)
+{
+ subspace.forEachMarkedCell(
+ [&] (HeapCell* cell, HeapCell::Kind) {
+ static_cast<CellType*>(cell)->finalizeUnconditionally(*vm());
+ });
+}
+
void Heap::finalizeUnconditionalFinalizers()
{
+ finalizeUnconditionalFinalizers<InferredStructure>(vm()->inferredStructureSpace);
+
while (m_unconditionalFinalizers.hasNext()) {
UnconditionalFinalizer* finalizer = m_unconditionalFinalizers.removeNext();
finalizer->finalizeUnconditionally();
Modified: trunk/Source/_javascript_Core/heap/Heap.h (225724 => 225725)
--- trunk/Source/_javascript_Core/heap/Heap.h 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/heap/Heap.h 2017-12-09 19:48:04 UTC (rev 225725)
@@ -495,7 +495,12 @@
void deleteSourceProviderCaches();
void notifyIncrementalSweeper();
void harvestWeakReferences();
+
+ template<typename CellType>
+ void finalizeUnconditionalFinalizers(Subspace&);
+
void finalizeUnconditionalFinalizers();
+
void clearUnmarkedExecutables();
void deleteUnmarkedCompiledCode();
JS_EXPORT_PRIVATE void addToRememberedSet(const JSCell*);
Added: trunk/Source/_javascript_Core/runtime/InferredStructure.cpp (0 => 225725)
--- trunk/Source/_javascript_Core/runtime/InferredStructure.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/InferredStructure.cpp 2017-12-09 19:48:04 UTC (rev 225725)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InferredStructure.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo InferredStructure::s_info = { "InferredStructure", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(InferredStructure) };
+
+InferredStructure* InferredStructure::create(VM& vm, GCDeferralContext& deferralContext, InferredType* parent, Structure* structure)
+{
+ InferredStructure* result = new (NotNull, allocateCell<InferredStructure>(vm.heap, &deferralContext)) InferredStructure(vm, parent, structure);
+ result->finishCreation(vm, structure);
+ return result;
+}
+
+void InferredStructure::destroy(JSCell* cell)
+{
+ InferredStructure* inferredStructure = static_cast<InferredStructure*>(cell);
+ inferredStructure->InferredStructure::~InferredStructure();
+}
+
+Structure* InferredStructure::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+ return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+}
+
+void InferredStructure::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+ InferredStructure* inferredStructure = jsCast<InferredStructure*>(cell);
+
+ visitor.append(inferredStructure->m_parent);
+}
+
+void InferredStructure::finalizeUnconditionally(VM&)
+{
+ ASSERT(Heap::isMarked(m_parent.get()));
+
+ // Monotonicity ensures that we shouldn't see a new structure that is different from us, but we
+ // could have been nulled. We only rely on it being the null case only in debug.
+ if (this == m_parent->m_structure.get()) {
+ if (!Heap::isMarked(m_structure.get()))
+ m_parent->removeStructure();
+ } else
+ ASSERT(!m_parent->m_structure);
+
+ // We'll get deleted on the next GC. That's a little weird, but not harmful, since it only happens
+ // when the InferredType that we were paired to would have survived. It just means a tiny missed
+ // opportunity for heap size reduction.
+}
+
+InferredStructure::InferredStructure(VM& vm, InferredType* parent, Structure* structure)
+ : Base(vm, vm.inferredStructureStructure.get())
+ , m_parent(vm, this, parent)
+ , m_structure(vm, this, structure)
+{
+}
+
+void InferredStructure::finishCreation(VM& vm, Structure* structure)
+{
+ Base::finishCreation(vm);
+ structure->addTransitionWatchpoint(&m_watchpoint);
+}
+
+} // namespace JSC
+
+
Added: trunk/Source/_javascript_Core/runtime/InferredStructure.h (0 => 225725)
--- trunk/Source/_javascript_Core/runtime/InferredStructure.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/InferredStructure.h 2017-12-09 19:48:04 UTC (rev 225725)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "InferredStructureWatchpoint.h"
+#include "JSCell.h"
+#include "VM.h"
+
+namespace JSC {
+
+class InferredType;
+
+class InferredStructure final : public JSCell {
+public:
+ typedef JSCell Base;
+
+ template<typename CellType>
+ static IsoSubspace* subspaceFor(VM& vm)
+ {
+ return &vm.inferredStructureSpace;
+ }
+
+ static InferredStructure* create(VM&, GCDeferralContext&, InferredType* parent, Structure*);
+
+ static const bool needsDestruction = true;
+ static void destroy(JSCell*);
+
+ static const unsigned StructureFlags = StructureIsImmortal | Base::StructureFlags;
+
+ static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
+
+ static void visitChildren(JSCell*, SlotVisitor&);
+
+ DECLARE_INFO;
+
+ InferredType* parent() const { return m_parent.get(); }
+ Structure* structure() const { return m_structure.get(); }
+
+ void finalizeUnconditionally(VM&);
+
+private:
+ InferredStructure(VM&, InferredType* parent, Structure*);
+
+ void finishCreation(VM&, Structure*);
+
+ WriteBarrier<InferredType> m_parent;
+ WriteBarrier<Structure> m_structure;
+
+ friend class InferredStructureWatchpoint;
+ InferredStructureWatchpoint m_watchpoint;
+};
+
+} // namespace JSC
+
Added: trunk/Source/_javascript_Core/runtime/InferredStructureWatchpoint.cpp (0 => 225725)
--- trunk/Source/_javascript_Core/runtime/InferredStructureWatchpoint.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/InferredStructureWatchpoint.cpp 2017-12-09 19:48:04 UTC (rev 225725)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InferredStructureWatchpoint.h"
+
+#include "InferredType.h"
+
+namespace JSC {
+
+void InferredStructureWatchpoint::fireInternal(const FireDetail&)
+{
+ InferredStructure* inferredStructure =
+ bitwise_cast<InferredStructure*>(
+ bitwise_cast<char*>(this) - OBJECT_OFFSETOF(InferredStructure, m_watchpoint));
+
+ if (!inferredStructure->isLive())
+ return;
+
+ inferredStructure->m_parent->removeStructure();
+}
+
+} // namespace JSC
+
Added: trunk/Source/_javascript_Core/runtime/InferredStructureWatchpoint.h (0 => 225725)
--- trunk/Source/_javascript_Core/runtime/InferredStructureWatchpoint.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/InferredStructureWatchpoint.h 2017-12-09 19:48:04 UTC (rev 225725)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "Watchpoint.h"
+
+namespace JSC {
+
+class InferredStructureWatchpoint : public Watchpoint {
+protected:
+ void fireInternal(const FireDetail&) override;
+};
+
+} // namespace JSC
+
Modified: trunk/Source/_javascript_Core/runtime/InferredType.cpp (225724 => 225725)
--- trunk/Source/_javascript_Core/runtime/InferredType.cpp 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/runtime/InferredType.cpp 2017-12-09 19:48:04 UTC (rev 225725)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,12 +26,11 @@
#include "config.h"
#include "InferredType.h"
+#include "GCDeferralContextInlines.h"
#include "JSCInlines.h"
namespace JSC {
-namespace {
-
class InferredTypeFireDetail : public FireDetail {
public:
InferredTypeFireDetail(
@@ -64,8 +63,6 @@
JSValue m_offendingValue;
};
-} // anonymous namespace
-
const ClassInfo InferredType::s_info = { "InferredType", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(InferredType) };
InferredType* InferredType::create(VM& vm)
@@ -89,15 +86,7 @@
void InferredType::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
InferredType* inferredType = jsCast<InferredType*>(cell);
-
- ConcurrentJSLocker locker(inferredType->m_lock);
-
- if (inferredType->m_structure) {
- // The mutator may clear the structure before the GC runs finalizers, so we have to protect
- // the finalizer from being destroyed.
- inferredType->m_structure->ref();
- visitor.addUnconditionalFinalizer(&inferredType->m_structure->m_finalizer);
- }
+ visitor.append(inferredType->m_structure);
}
InferredType::Kind InferredType::kindForFlags(PutByIdFlags flags)
@@ -410,6 +399,7 @@
Descriptor myType;
bool result;
{
+ GCDeferralContext deferralContext(vm.heap);
ConcurrentJSLocker locker(m_lock);
oldType = descriptor(locker);
myType = Descriptor::forValue(value);
@@ -418,7 +408,7 @@
ASSERT(oldType != myType); // The type must have changed if we're on the slow path.
- bool setResult = set(locker, vm, myType);
+ bool setResult = set(deferralContext, locker, vm, myType);
result = kind(locker) != Top;
if (!setResult)
return result;
@@ -433,9 +423,10 @@
{
Descriptor oldType;
{
+ GCDeferralContext deferralContext(vm.heap);
ConcurrentJSLocker locker(m_lock);
oldType = descriptor(locker);
- if (!set(locker, vm, Top))
+ if (!set(deferralContext, locker, vm, Top))
return;
}
@@ -443,7 +434,7 @@
m_watchpointSet.fireAll(vm, detail);
}
-bool InferredType::set(const ConcurrentJSLocker& locker, VM& vm, Descriptor newDescriptor)
+bool InferredType::set(GCDeferralContext& deferralContext, const ConcurrentJSLocker& locker, VM& vm, Descriptor newDescriptor)
{
// We will trigger write barriers while holding our lock. Currently, write barriers don't GC, but that
// could change. If it does, we don't want to deadlock. Note that we could have used
@@ -480,7 +471,7 @@
// Remove the old InferredStructure object if we no longer need it.
if (!newDescriptor.structure())
- m_structure = nullptr;
+ m_structure.clear();
// Add a new InferredStructure object if we need one now.
if (newDescriptor.structure()) {
@@ -488,8 +479,8 @@
// We should agree on the structures if we get here.
ASSERT(newDescriptor.structure() == m_structure->structure());
} else {
- m_structure = adoptRef(new InferredStructure(vm, this, newDescriptor.structure()));
- newDescriptor.structure()->addTransitionWatchpoint(&m_structure->m_watchpoint);
+ auto* structure = InferredStructure::create(vm, deferralContext, this, newDescriptor.structure());
+ m_structure.set(vm, this, structure);
}
}
@@ -512,12 +503,13 @@
Descriptor oldDescriptor;
Descriptor newDescriptor;
{
+ GCDeferralContext deferralContext(vm.heap);
ConcurrentJSLocker locker(m_lock);
oldDescriptor = descriptor(locker);
newDescriptor = oldDescriptor;
newDescriptor.removeStructure();
- if (!set(locker, vm, newDescriptor))
+ if (!set(deferralContext, locker, vm, newDescriptor))
return;
}
@@ -525,40 +517,6 @@
m_watchpointSet.fireAll(vm, detail);
}
-void InferredType::InferredStructureWatchpoint::fireInternal(const FireDetail&)
-{
- InferredStructure* inferredStructure =
- bitwise_cast<InferredStructure*>(
- bitwise_cast<char*>(this) - OBJECT_OFFSETOF(InferredStructure, m_watchpoint));
-
- inferredStructure->m_parent->removeStructure();
-}
-
-void InferredType::InferredStructureFinalizer::finalizeUnconditionally()
-{
- InferredStructure* inferredStructure =
- bitwise_cast<InferredStructure*>(
- bitwise_cast<char*>(this) - OBJECT_OFFSETOF(InferredStructure, m_finalizer));
-
- ASSERT(Heap::isMarked(inferredStructure->m_parent));
-
- // Monotonicity ensures that we shouldn't see a new structure that is different from us, but we
- // could have been nulled. We only rely on it being the null case only in debug.
- if (inferredStructure == inferredStructure->m_parent->m_structure.get()) {
- if (!Heap::isMarked(inferredStructure->m_structure.get()))
- inferredStructure->m_parent->removeStructure();
- } else
- ASSERT(!inferredStructure->m_parent->m_structure);
-
- inferredStructure->deref();
-}
-
-InferredType::InferredStructure::InferredStructure(VM& vm, InferredType* parent, Structure* structure)
- : m_parent(parent)
- , m_structure(vm, parent, structure)
-{
-}
-
} // namespace JSC
namespace WTF {
Modified: trunk/Source/_javascript_Core/runtime/InferredType.h (225724 => 225725)
--- trunk/Source/_javascript_Core/runtime/InferredType.h 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/runtime/InferredType.h 2017-12-09 19:48:04 UTC (rev 225725)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
#pragma once
#include "ConcurrentJSLock.h"
+#include "InferredStructure.h"
#include "JSCell.h"
#include "PropertyName.h"
#include "PutByIdFlags.h"
@@ -40,6 +41,12 @@
public:
typedef JSCell Base;
+ template<typename CellType>
+ static IsoSubspace* subspaceFor(VM& vm)
+ {
+ return &vm.inferredTypeSpace;
+ }
+
static InferredType* create(VM&);
static const bool needsDestruction = true;
@@ -222,6 +229,8 @@
void addWatchpoint(Watchpoint*);
void dump(PrintStream&) const;
+
+ void finalizeUnconditionally();
private:
InferredType(VM&);
@@ -232,48 +241,19 @@
// Helper for willStoreValueSlow() and makeTopSlow(). This returns true if we should fire the
// watchpoint set.
- bool set(const ConcurrentJSLocker&, VM&, Descriptor);
+ bool set(GCDeferralContext&, const ConcurrentJSLocker&, VM&, Descriptor);
void removeStructure();
+
+ friend class InferredStructure;
+ friend class InferredStructureWatchpoint;
mutable ConcurrentJSLock m_lock;
Kind m_kind { Bottom };
- class InferredStructureWatchpoint : public Watchpoint {
- public:
- InferredStructureWatchpoint() { }
- protected:
- void fireInternal(const FireDetail&) override;
- };
+ WriteBarrier<InferredStructure> m_structure;
- class InferredStructureFinalizer : public UnconditionalFinalizer {
- public:
- InferredStructureFinalizer() { }
- protected:
- void finalizeUnconditionally() override;
- };
-
- class InferredStructure : public ThreadSafeRefCounted<InferredStructure> {
- public:
- InferredStructure(VM&, InferredType* parent, Structure*);
-
- Structure* structure() const { return m_structure.get(); };
-
- private:
- friend class InferredType;
- friend class InferredStructureWatchpoint;
- friend class InferredStructureFinalizer;
-
- InferredType* m_parent;
- WriteBarrier<Structure> m_structure;
-
- InferredStructureWatchpoint m_watchpoint;
- InferredStructureFinalizer m_finalizer;
- };
-
- RefPtr<InferredStructure> m_structure;
-
// NOTE: If this is being watched, we transform to Top because that implies that it wouldn't be
// profitable to watch it again. Also, this set is initialized clear, and is never exposed to the DFG
// thread. The DFG will use the InferredType as the thing that it watches.
Modified: trunk/Source/_javascript_Core/runtime/PrototypeKey.h (225724 => 225725)
--- trunk/Source/_javascript_Core/runtime/PrototypeKey.h 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/runtime/PrototypeKey.h 2017-12-09 19:48:04 UTC (rev 225725)
@@ -29,6 +29,10 @@
namespace JSC {
+class FunctionExecutable;
+class JSGlobalObject;
+class JSObject;
+
class PrototypeKey {
public:
PrototypeKey() { }
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (225724 => 225725)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2017-12-09 19:48:04 UTC (rev 225725)
@@ -202,11 +202,13 @@
#if ENABLE(WEBASSEMBLY)
, webAssemblyCodeBlockSpace("JSWebAssemblyCodeBlockSpace", heap, webAssemblyCodeBlockHeapCellType.get(), fastMallocAllocator.get())
#endif
- , nativeExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), NativeExecutable)
, directEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), DirectEvalExecutable)
+ , functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable)
, indirectEvalExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), IndirectEvalExecutable)
- , functionExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), FunctionExecutable)
+ , inferredStructureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), InferredStructure)
+ , inferredTypeSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), InferredType)
, moduleProgramExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ModuleProgramExecutable)
+ , nativeExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), NativeExecutable)
, programExecutableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), ProgramExecutable)
, vmType(vmType)
, clientData(0)
@@ -290,9 +292,10 @@
unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
unlinkedModuleProgramCodeBlockStructure.set(*this, UnlinkedModuleProgramCodeBlock::createStructure(*this, 0, jsNull()));
propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
- inferredValueStructure.set(*this, InferredValue::createStructure(*this, 0, jsNull()));
+ inferredStructureStructure.set(*this, InferredStructure::createStructure(*this, 0, jsNull()));
inferredTypeStructure.set(*this, InferredType::createStructure(*this, 0, jsNull()));
inferredTypeTableStructure.set(*this, InferredTypeTable::createStructure(*this, 0, jsNull()));
+ inferredValueStructure.set(*this, InferredValue::createStructure(*this, 0, jsNull()));
functionRareDataStructure.set(*this, FunctionRareData::createStructure(*this, 0, jsNull()));
exceptionStructure.set(*this, Exception::createStructure(*this, 0, jsNull()));
promiseDeferredStructure.set(*this, JSPromiseDeferred::createStructure(*this, 0, jsNull()));
Modified: trunk/Source/_javascript_Core/runtime/VM.h (225724 => 225725)
--- trunk/Source/_javascript_Core/runtime/VM.h 2017-12-09 16:58:36 UTC (rev 225724)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2017-12-09 19:48:04 UTC (rev 225725)
@@ -337,11 +337,13 @@
CompleteSubspace webAssemblyCodeBlockSpace;
#endif
- IsoSubspace nativeExecutableSpace;
IsoSubspace directEvalExecutableSpace;
+ IsoSubspace functionExecutableSpace;
IsoSubspace indirectEvalExecutableSpace;
- IsoSubspace functionExecutableSpace;
+ IsoSubspace inferredStructureSpace;
+ IsoSubspace inferredTypeSpace;
IsoSubspace moduleProgramExecutableSpace;
+ IsoSubspace nativeExecutableSpace;
IsoSubspace programExecutableSpace;
VMType vmType;
@@ -390,9 +392,10 @@
Strong<Structure> unlinkedFunctionCodeBlockStructure;
Strong<Structure> unlinkedModuleProgramCodeBlockStructure;
Strong<Structure> propertyTableStructure;
- Strong<Structure> inferredValueStructure;
+ Strong<Structure> inferredStructureStructure;
Strong<Structure> inferredTypeStructure;
Strong<Structure> inferredTypeTableStructure;
+ Strong<Structure> inferredValueStructure;
Strong<Structure> functionRareDataStructure;
Strong<Structure> exceptionStructure;
Strong<Structure> promiseDeferredStructure;