Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (209637 => 209638)
--- trunk/Source/_javascript_Core/ChangeLog 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-12-10 01:22:15 UTC (rev 209638)
@@ -1,3 +1,80 @@
+2016-12-09 Filip Pizlo <fpi...@apple.com>
+
+ GC might be forced to look at a nuked object due to ordering of AllocatePropertyStorage, MaterializeNewObject, and PutStructure
+ https://bugs.webkit.org/show_bug.cgi?id=165672
+
+ Reviewed by Geoffrey Garen.
+
+ We need to make sure that the shady stuff in a property put happens after the
+ PutByOffset, since the PutByOffset is the place where we materialize. More generally, we
+ should strive to not have any fenceposts between Nodes where a GC would be illegal.
+
+ This gets us most of the way there by separating NukeStructureAndSetButterfly from
+ [Re]AllocatePropertyStorage. A transitioning put will now look something like:
+
+ GetButterfly
+ ReallocatePropertyStorage
+ PutByOffset
+ NukeStructureAndSetButterfly
+ PutStructure
+
+ Previously the structure would get nuked by ReallocatePropertyStorage, so if we placed
+ an object materialization just after it (before the PutByOffset) then any GC that
+ completed at that safepoint would encounter an unresolved visit race due to seeing a
+ nuked structure. We cannot have nuked structures at safepoints, and this change makes
+ sure that we don't - at least until someone tries to sink to the PutStructure. We will
+ eventually have to create a combined SetStructureAndButterfly node, but we don't need it
+ yet.
+
+ This also fixes a goof where the DFG's AllocatePropertyStorage was nulling the structure
+ instead of nuking it. This could easily have caused many crashes in GC.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handlePutById):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGClobbersExitState.cpp:
+ (JSC::DFG::clobbersExitState):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::emitPutByOffset):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGMayExit.cpp:
+ * dfg/DFGNodeType.h:
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage):
+ (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage):
+ (JSC::DFG::SpeculativeJIT::compileNukeStructureAndSetButterfly):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStoreBarrierInsertionPhase.cpp:
+ * dfg/DFGTypeCheckHoistingPhase.cpp:
+ (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+ (JSC::FTL::DFG::LowerDFGToB3::compileNukeStructureAndSetButterfly):
+ (JSC::FTL::DFG::LowerDFGToB3::storageForTransition):
+ (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorage):
+ (JSC::FTL::DFG::LowerDFGToB3::reallocatePropertyStorage):
+ (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl):
+ * runtime/Options.cpp:
+ (JSC::recomputeDependentOptions):
+ * runtime/Options.h: Fix a bug - make it possible to turn on concurrent GC optionally again.
+
2016-12-09 Chris Dumez <cdu...@apple.com>
Inline JSCell::toObject()
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2016-12-10 01:22:15 UTC (rev 209638)
@@ -2309,6 +2309,7 @@
case GetButterfly:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
+ case NukeStructureAndSetButterfly:
// FIXME: We don't model the fact that the structureID is nuked, simply because currently
// nobody would currently benefit from having that information. But it's a bug nonetheless.
forNode(node).clear(); // The result is not a JS value.
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -3594,6 +3594,13 @@
data->inferredType = variant.requiredType();
m_graph.registerInferredType(data->inferredType);
+ // NOTE: We could GC at this point because someone could insert an operation that GCs.
+ // That's fine because:
+ // - Things already in the structure will get scanned because we haven't messed with
+ // the object yet.
+ // - The value we are fixing to put is going to be kept live by OSR exit handling. So
+ // if the GC does a conservative scan here it will see the new value.
+
addToGraph(
PutByOffset,
OpInfo(data),
@@ -3600,6 +3607,9 @@
propertyStorage,
base,
value);
+
+ if (variant.reallocatesStorage())
+ addToGraph(NukeStructureAndSetButterfly, base, propertyStorage);
// FIXME: PutStructure goes last until we fix either
// https://bugs.webkit.org/show_bug.cgi?id=142921 or
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2016-12-10 01:22:15 UTC (rev 209638)
@@ -891,7 +891,7 @@
return;
case PutStructure:
- read(JSObject_butterfly); // This is a store-store fence.
+ read(JSObject_butterfly);
write(JSCell_structureID);
write(JSCell_typeInfoType);
write(JSCell_typeInfoFlags);
@@ -899,16 +899,15 @@
return;
case AllocatePropertyStorage:
- write(JSObject_butterfly);
- write(JSCell_structureID);
- def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node));
+ case ReallocatePropertyStorage:
+ read(HeapObjectCount);
+ write(HeapObjectCount);
return;
- case ReallocatePropertyStorage:
- read(JSObject_butterfly);
+ case NukeStructureAndSetButterfly:
write(JSObject_butterfly);
write(JSCell_structureID);
- def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node));
+ def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node->child2().node()));
return;
case GetButterfly:
Modified: trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -68,6 +68,8 @@
case CountExecution:
case StoreBarrier:
case FencedStoreBarrier:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
// These do clobber memory, but nothing that is observable. It may be nice to separate the
// heaps into those that are observable and those that aren't, but we don't do that right now.
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=148440
Modified: trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -766,6 +766,7 @@
DFG_ASSERT(m_graph, node, origin.exitOK);
bool canExit = true;
+ bool didAllocateStorage = false;
if (isInlineOffset(variant.offset()))
propertyStorage = childEdge;
@@ -777,8 +778,9 @@
ASSERT(!isInlineOffset(variant.offset()));
Node* allocatePropertyStorage = m_insertionSet.insertNode(
indexInBlock, SpecNone, AllocatePropertyStorage,
- origin.takeValidExit(canExit), OpInfo(transition), childEdge);
+ origin, OpInfo(transition), childEdge);
propertyStorage = Edge(allocatePropertyStorage);
+ didAllocateStorage = true;
} else {
ASSERT(variant.oldStructureForTransition()->outOfLineCapacity());
ASSERT(variant.newStructure()->outOfLineCapacity() > variant.oldStructureForTransition()->outOfLineCapacity());
@@ -785,11 +787,12 @@
ASSERT(!isInlineOffset(variant.offset()));
Node* reallocatePropertyStorage = m_insertionSet.insertNode(
- indexInBlock, SpecNone, ReallocatePropertyStorage, origin.takeValidExit(canExit),
+ indexInBlock, SpecNone, ReallocatePropertyStorage, origin,
OpInfo(transition), childEdge,
Edge(m_insertionSet.insertNode(
indexInBlock, SpecNone, GetButterfly, origin, childEdge)));
propertyStorage = Edge(reallocatePropertyStorage);
+ didAllocateStorage = true;
}
StorageAccessData& data = ""
@@ -800,6 +803,12 @@
node->origin.exitOK = canExit;
if (variant.kind() == PutByIdVariant::Transition) {
+ if (didAllocateStorage) {
+ m_insertionSet.insertNode(
+ indexInBlock + 1, SpecNone, NukeStructureAndSetButterfly,
+ origin.withInvalidExit(), childEdge, propertyStorage);
+ }
+
// FIXME: PutStructure goes last until we fix either
// https://bugs.webkit.org/show_bug.cgi?id=142921 or
// https://bugs.webkit.org/show_bug.cgi?id=142924.
Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -267,6 +267,7 @@
case GetDynamicVar:
case PutDynamicVar:
case ResolveScope:
+ case NukeStructureAndSetButterfly:
return false;
case CreateActivation:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -1199,6 +1199,11 @@
fixEdge<KnownCellUse>(node->child1());
break;
}
+
+ case NukeStructureAndSetButterfly: {
+ fixEdge<KnownCellUse>(node->child1());
+ break;
+ }
case TryGetById: {
if (node->child1()->shouldSpeculateCell())
Modified: trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -91,6 +91,7 @@
case PutByOffset:
case PutClosureVar:
case RecordRegExpCachedResult:
+ case NukeStructureAndSetButterfly:
break;
case StrCat:
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2016-12-10 01:22:15 UTC (rev 209638)
@@ -208,6 +208,7 @@
macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
macro(GetButterfly, NodeResultStorage) \
+ macro(NukeStructureAndSetButterfly, NodeMustGenerate) \
macro(CheckArray, NodeMustGenerate) \
macro(Arrayify, NodeMustGenerate) \
macro(ArrayifyToStructure, NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -1480,7 +1480,7 @@
return static_cast<int32_t>(TypeofType::Object);
}
-char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
+char* JIT_OPERATION operationAllocateSimplePropertyStorageWithInitialCapacity(ExecState* exec)
{
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
@@ -1489,7 +1489,7 @@
Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
}
-char* JIT_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
+char* JIT_OPERATION operationAllocateSimplePropertyStorage(ExecState* exec, size_t newSize)
{
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
@@ -1498,6 +1498,25 @@
Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
}
+char* JIT_OPERATION operationAllocateComplexPropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ ASSERT(!object->structure()->outOfLineCapacity());
+ return reinterpret_cast<char*>(
+ object->allocateMoreOutOfLineStorage(vm, 0, initialOutOfLineCapacity));
+}
+
+char* JIT_OPERATION operationAllocateComplexPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return reinterpret_cast<char*>(
+ object->allocateMoreOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize));
+}
+
char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
{
VM& vm = exec->vm();
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.h 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h 2016-12-10 01:22:15 UTC (rev 209638)
@@ -146,8 +146,10 @@
size_t JIT_OPERATION operationObjectIsFunction(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
JSCell* JIT_OPERATION operationTypeOfObject(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
-char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
-char* JIT_OPERATION operationAllocatePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL;
+char* JIT_OPERATION operationAllocateSimplePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
+char* JIT_OPERATION operationAllocateSimplePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL;
+char* JIT_OPERATION operationAllocateComplexPropertyStorageWithInitialCapacity(ExecState*, JSObject*) WTF_INTERNAL;
+char* JIT_OPERATION operationAllocateComplexPropertyStorage(ExecState*, JSObject*, size_t newSize) WTF_INTERNAL;
char* JIT_OPERATION operationEnsureInt32(ExecState*, JSCell*);
char* JIT_OPERATION operationEnsureDouble(ExecState*, JSCell*);
char* JIT_OPERATION operationEnsureContiguous(ExecState*, JSCell*);
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -1105,6 +1105,7 @@
case LoadVarargs:
case ForwardVarargs:
case PutDynamicVar:
+ case NukeStructureAndSetButterfly:
break;
// This gets ignored because it only pretends to produce a value.
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2016-12-10 01:22:15 UTC (rev 209638)
@@ -389,6 +389,8 @@
case StoreBarrier:
case FencedStoreBarrier:
+ case PutStructure:
+ case NukeStructureAndSetButterfly:
// We conservatively assume that these cannot be put anywhere, which forces the compiler to
// keep them exactly where they were. This is sort of overkill since the clobberize effects
// already force these things to be ordered precisely. I'm just not confident enough in my
@@ -413,7 +415,6 @@
return node->arrayMode().modeForPut().alreadyChecked(
graph, node, state.forNode(graph.varArgChild(node, 0)));
- case PutStructure:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
return state.forNode(node->child1()).m_structure.isSubsetOf(
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -7389,7 +7389,7 @@
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationReallocateButterflyToHavePropertyStorageWithInitialCapacity, result.gpr(), baseGPR);
+ callOperation(operationAllocateComplexPropertyStorageWithInitialCapacity, result.gpr(), baseGPR);
m_jit.exceptionCheck();
storageResult(result.gpr(), node);
@@ -7396,12 +7396,10 @@
return;
}
- SpeculateCellOperand base(this, node->child1());
GPRTemporary scratch1(this);
GPRTemporary scratch2(this);
GPRTemporary scratch3(this);
- GPRReg baseGPR = base.gpr();
GPRReg scratchGPR1 = scratch1.gpr();
GPRReg scratchGPR2 = scratch2.gpr();
GPRReg scratchGPR3 = scratch3.gpr();
@@ -7415,11 +7413,8 @@
m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(scratchGPR1, -(offset + sizeof(JSValue) + sizeof(void*))));
addSlowPathGenerator(
- slowPathCall(slowPath, this, operationAllocatePropertyStorageWithInitialCapacity, scratchGPR1));
+ slowPathCall(slowPath, this, operationAllocateSimplePropertyStorageWithInitialCapacity, scratchGPR1));
- m_jit.store32(TrustedImm32(0), JITCompiler::Address(baseGPR, JSCell::structureIDOffset()));
- m_jit.storeButterfly(scratchGPR1, baseGPR);
-
storageResult(scratchGPR1, node);
}
@@ -7439,7 +7434,7 @@
flushRegisters();
GPRFlushedCallResult result(this);
- callOperation(operationReallocateButterflyToGrowPropertyStorage, result.gpr(), baseGPR, newSize / sizeof(JSValue));
+ callOperation(operationAllocateComplexPropertyStorage, result.gpr(), baseGPR, newSize / sizeof(JSValue));
m_jit.exceptionCheck();
storageResult(result.gpr(), node);
@@ -7446,13 +7441,11 @@
return;
}
- SpeculateCellOperand base(this, node->child1());
StorageOperand oldStorage(this, node->child2());
GPRTemporary scratch1(this);
GPRTemporary scratch2(this);
GPRTemporary scratch3(this);
- GPRReg baseGPR = base.gpr();
GPRReg oldStorageGPR = oldStorage.gpr();
GPRReg scratchGPR1 = scratch1.gpr();
GPRReg scratchGPR2 = scratch2.gpr();
@@ -7468,7 +7461,7 @@
m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(scratchGPR1, -(offset + sizeof(JSValue) + sizeof(void*))));
addSlowPathGenerator(
- slowPathCall(slowPath, this, operationAllocatePropertyStorage, scratchGPR1, newSize / sizeof(JSValue)));
+ slowPathCall(slowPath, this, operationAllocateSimplePropertyStorage, scratchGPR1, newSize / sizeof(JSValue)));
// We have scratchGPR1 = new storage, scratchGPR2 = scratch
for (ptrdiff_t offset = 0; offset < static_cast<ptrdiff_t>(oldSize); offset += sizeof(void*)) {
@@ -7476,11 +7469,22 @@
m_jit.storePtr(scratchGPR2, JITCompiler::Address(scratchGPR1, -(offset + sizeof(JSValue) + sizeof(void*))));
}
- m_jit.nukeStructureAndStoreButterfly(scratchGPR1, baseGPR);
-
storageResult(scratchGPR1, node);
}
+void SpeculativeJIT::compileNukeStructureAndSetButterfly(Node* node)
+{
+ SpeculateCellOperand base(this, node->child1());
+ StorageOperand storage(this, node->child2());
+
+ GPRReg baseGPR = base.gpr();
+ GPRReg storageGPR = storage.gpr();
+
+ m_jit.nukeStructureAndStoreButterfly(storageGPR, baseGPR);
+
+ noResult(node);
+}
+
void SpeculativeJIT::compileGetButterfly(Node* node)
{
SpeculateCellOperand base(this, node->child1());
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2016-12-10 01:22:15 UTC (rev 209638)
@@ -2579,6 +2579,7 @@
void compileAllocatePropertyStorage(Node*);
void compileReallocatePropertyStorage(Node*);
+ void compileNukeStructureAndSetButterfly(Node*);
void compileGetButterfly(Node*);
void compileCallDOMGetter(Node*);
void compileCallDOM(Node*);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -4429,6 +4429,10 @@
compileReallocatePropertyStorage(node);
break;
+ case NukeStructureAndSetButterfly:
+ compileNukeStructureAndSetButterfly(node);
+ break;
+
case GetButterfly:
compileGetButterfly(node);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -4395,6 +4395,10 @@
compileReallocatePropertyStorage(node);
break;
+ case NukeStructureAndSetButterfly:
+ compileNukeStructureAndSetButterfly(node);
+ break;
+
case GetButterfly:
compileGetButterfly(node);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -296,6 +296,11 @@
considerBarrier(m_node->child1(), m_node->child2());
break;
}
+
+ case NukeStructureAndSetButterfly: {
+ considerBarrier(m_node->child1());
+ break;
+ }
default:
break;
@@ -322,17 +327,13 @@
case NewFunction:
case NewGeneratorFunction:
case NewAsyncFunction:
+ case AllocatePropertyStorage:
+ case ReallocatePropertyStorage:
// Nodes that allocate get to set their epoch because for those nodes we know
// that they will be the newest object in the heap.
m_node->setEpoch(m_currentEpoch);
break;
- case AllocatePropertyStorage:
- case ReallocatePropertyStorage:
- insertBarrier(m_nodeIndex + 1, m_node->child1());
- m_node->setEpoch(Epoch());
- break;
-
case Upsilon:
// Assume the worst for Phis so that we don't have to worry about Phi shadows.
m_node->phi()->setEpoch(Epoch());
Modified: trunk/Source/_javascript_Core/dfg/DFGTypeCheckHoistingPhase.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/dfg/DFGTypeCheckHoistingPhase.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/dfg/DFGTypeCheckHoistingPhase.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -246,6 +246,7 @@
case PutStructure:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
+ case NukeStructureAndSetButterfly:
case GetButterfly:
case GetByVal:
case PutByValDirect:
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -139,6 +139,7 @@
case StringFromCharCode:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
+ case NukeStructureAndSetButterfly:
case GetTypedArrayByteOffset:
case NotifyWrite:
case StoreBarrier:
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -753,6 +753,9 @@
case ReallocatePropertyStorage:
compileReallocatePropertyStorage();
break;
+ case NukeStructureAndSetButterfly:
+ compileNukeStructureAndSetButterfly();
+ break;
case ToNumber:
compileToNumber();
break;
@@ -4752,6 +4755,11 @@
reallocatePropertyStorage(
object, oldStorage, transition->previous, transition->next));
}
+
+ void compileNukeStructureAndSetButterfly()
+ {
+ nukeStructureAndSetButterfly(lowStorage(m_node->child2()), lowCell(m_node->child1()));
+ }
void compileToNumber()
{
@@ -9406,6 +9414,7 @@
previousStructure, nextStructure);
}
+ nukeStructureAndSetButterfly(result, object);
return result;
}
@@ -9475,8 +9484,7 @@
if (previousStructure->couldHaveIndexingHeader()) {
return vmCall(
pointerType(),
- m_out.operation(
- operationReallocateButterflyToHavePropertyStorageWithInitialCapacity),
+ m_out.operation(operationAllocateComplexPropertyStorageWithInitialCapacity),
m_callFrame, object);
}
@@ -9487,7 +9495,6 @@
m_out.constInt32(-initialOutOfLineCapacity - 1), m_out.constInt32(-1),
m_out.int64Zero, m_heaps.properties.atAnyNumber());
- nukeStructureAndSetButterfly(result, object);
return result;
}
@@ -9501,7 +9508,7 @@
if (previous->couldHaveIndexingHeader()) {
LValue newAllocSize = m_out.constIntPtr(newSize);
- return vmCall(pointerType(), m_out.operation(operationReallocateButterflyToGrowPropertyStorage), m_callFrame, object, newAllocSize);
+ return vmCall(pointerType(), m_out.operation(operationAllocateComplexPropertyStorage), m_callFrame, object, newAllocSize);
}
LValue result = allocatePropertyStorageWithSizeImpl(newSize);
@@ -9520,8 +9527,6 @@
m_out.constInt32(-newSize - 1), m_out.constInt32(-oldSize - 1),
m_out.int64Zero, m_heaps.properties.atAnyNumber());
- nukeStructureAndSetButterfly(result, object);
-
return result;
}
@@ -9546,7 +9551,7 @@
slowButterflyValue = lazySlowPath(
[=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
return createLazyCallGenerator(
- operationAllocatePropertyStorageWithInitialCapacity,
+ operationAllocateSimplePropertyStorageWithInitialCapacity,
locations[0].directGPR());
});
} else {
@@ -9553,7 +9558,7 @@
slowButterflyValue = lazySlowPath(
[=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
return createLazyCallGenerator(
- operationAllocatePropertyStorage, locations[0].directGPR(),
+ operationAllocateSimplePropertyStorage, locations[0].directGPR(),
CCallHelpers::TrustedImmPtr(sizeInValues));
});
}
Modified: trunk/Source/_javascript_Core/runtime/Options.cpp (209637 => 209638)
--- trunk/Source/_javascript_Core/runtime/Options.cpp 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/runtime/Options.cpp 2016-12-10 01:22:15 UTC (rev 209638)
@@ -332,7 +332,7 @@
Options::useFTLJIT() = false;
#endif
-#if 1 || (!CPU(X86_64) && !CPU(ARM64))
+#if !CPU(X86_64) && !CPU(ARM64)
Options::useConcurrentGC() = false;
#endif
Modified: trunk/Source/_javascript_Core/runtime/Options.h (209637 => 209638)
--- trunk/Source/_javascript_Core/runtime/Options.h 2016-12-10 00:06:10 UTC (rev 209637)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2016-12-10 01:22:15 UTC (rev 209638)
@@ -184,7 +184,7 @@
v(bool, verboseSanitizeStack, false, Normal, nullptr) \
v(bool, useGenerationalGC, true, Normal, nullptr) \
v(bool, useConcurrentBarriers, true, Normal, nullptr) \
- v(bool, useConcurrentGC, true, Normal, nullptr) \
+ v(bool, useConcurrentGC, false, Normal, nullptr) \
v(bool, collectContinuously, false, Normal, nullptr) \
v(double, collectContinuouslyPeriodMS, 1, Normal, nullptr) \
v(bool, forceFencedBarrier, false, Normal, nullptr) \