Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (215884 => 215885)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2017-04-27 19:24:07 UTC (rev 215885)
@@ -713,6 +713,7 @@
runtime/DirectArguments.cpp
runtime/DirectArgumentsOffset.cpp
runtime/DirectEvalExecutable.cpp
+ runtime/DisallowVMReentry.cpp
runtime/DumpContext.cpp
runtime/ECMAScriptSpecInternalFunctions.cpp
runtime/Error.cpp
@@ -852,6 +853,7 @@
runtime/NumberObject.cpp
runtime/NumberPrototype.cpp
runtime/ObjectConstructor.cpp
+ runtime/ObjectInitializationScope.cpp
runtime/ObjectPrototype.cpp
runtime/Operations.cpp
runtime/Options.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (215884 => 215885)
--- trunk/Source/_javascript_Core/ChangeLog 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1,3 +1,143 @@
+2017-04-27 Mark Lam <mark....@apple.com>
+
+ Audit and fix incorrect uses of JSArray::tryCreateForInitializationPrivate().
+ https://bugs.webkit.org/show_bug.cgi?id=171344
+ <rdar://problem/31352667>
+
+ Reviewed by Filip Pizlo.
+
+ JSArray::tryCreateForInitializationPrivate() should only be used in performance
+ critical paths, and should always be used with care because it creates an
+ uninitialized object that needs to be initialized by its client before the object
+ can be released into the system. Before the object is fully initialized:
+ a. the client should not re-enter the VM to execute JS code, and
+ b. GC should not run.
+
+ This is because until the object is fully initialized, it is an inconsistent
+ state that the GC and JS code will not be happy about.
+
+ In this patch, we do the following:
+
+ 1. Renamed JSArray::tryCreateForInitializationPrivate() to
+ JSArray::tryCreateUninitializedRestricted() because "private" is a bit ambiguous
+ and can be confused with APIs that are called freely within WebKit but are
+ not meant for clients of WebKit. In this case, we intend for use of this API
+ to be restricted to only a few carefully considered and crafted cases.
+
+ 2. Introduce the ObjectInitializationScope RAII object which covers the period
+ when the uninitialized object is created and gets initialized.
+
+ ObjectInitializationScope will asserts that either the object is created
+ fully initialized (in the case where the object structure is not an "original"
+ structure) or if created uninitialized, is fully initialized at the end of
+ the scope.
+
+ If the object is created uninitialized, the ObjectInitializationScope also
+ ensures that we do not GC nor re-enter the VM to execute JS code. This is
+ achieved by enabling DisallowGC and DisallowVMReentry scopes.
+
+ tryCreateUninitializedRestricted() and initializeIndex() now requires an
+ ObjectInitializationScope instance. The ObjectInitializationScope replaces
+ the VM& argument because it can be used to pass the VM& itself. This is a
+ small optimization that makes passing the ObjectInitializationScope free even
+ on release builds.
+
+ 3. Factored a DisallowScope out of DisallowGC, and make DisallowGC extend it.
+ Introduce a DisallowVMReentry class that extends DisallowScope.
+
+ 4. Fixed a bug found by the ObjectInitializationScope. The bug is that there are
+ scenarios where the structure passed to tryCreateUninitializedRestricted()
+ that may not be an "original" structure. As a result, initializeIndex() would
+ end up allocating new structures, and therefore trigger a GC.
+
+ The fix is to detect that the structure passed to tryCreateUninitializedRestricted()
+ is not an "original" one, and pre-initialize the array with 0s.
+
+ This bug was detected by existing tests. Hence, no new test needed.
+
+ 5. Replaced all inappropriate uses of tryCreateUninitializedRestricted() with
+ tryCreate(). Inappropriate uses here means code that is not in performance
+ critical paths.
+
+ Similarly, replaced accompanying uses of initializeIndex() with putDirectIndex().
+
+ This patch is performance neutral (according to the JSC command line benchmarks).
+
+ * CMakeLists.txt:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * dfg/DFGOperations.cpp:
+ * ftl/FTLOperations.cpp:
+ (JSC::FTL::operationMaterializeObjectInOSR):
+ * heap/DeferGC.cpp:
+ * heap/DeferGC.h:
+ (JSC::DisallowGC::DisallowGC):
+ (JSC::DisallowGC::initialize):
+ (JSC::DisallowGC::scopeReentryCount):
+ (JSC::DisallowGC::setScopeReentryCount):
+ (JSC::DisallowGC::~DisallowGC): Deleted.
+ (JSC::DisallowGC::isGCDisallowedOnCurrentThread): Deleted.
+ * heap/GCDeferralContextInlines.h:
+ (JSC::GCDeferralContext::~GCDeferralContext):
+ * heap/Heap.cpp:
+ (JSC::Heap::collectIfNecessaryOrDefer):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoPrivateFuncConcatMemcpy):
+ * runtime/ClonedArguments.cpp:
+ (JSC::ClonedArguments::createWithInlineFrame):
+ (JSC::ClonedArguments::createByCopyingFrom):
+ * runtime/CommonSlowPaths.cpp:
+ (JSC::SLOW_PATH_DECL):
+ * runtime/DisallowScope.h: Added.
+ (JSC::DisallowScope::DisallowScope):
+ (JSC::DisallowScope::~DisallowScope):
+ (JSC::DisallowScope::isInEffectOnCurrentThread):
+ (JSC::DisallowScope::enable):
+ (JSC::DisallowScope::enterScope):
+ (JSC::DisallowScope::exitScope):
+ * runtime/DisallowVMReentry.cpp: Added.
+ * runtime/DisallowVMReentry.h: Added.
+ (JSC::DisallowVMReentry::DisallowVMReentry):
+ (JSC::DisallowVMReentry::initialize):
+ (JSC::DisallowVMReentry::scopeReentryCount):
+ (JSC::DisallowVMReentry::setScopeReentryCount):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreading):
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::tryCreateUninitializedRestricted):
+ (JSC::JSArray::fastSlice):
+ (JSC::JSArray::tryCreateForInitializationPrivate): Deleted.
+ * runtime/JSArray.h:
+ (JSC::JSArray::tryCreateUninitializedRestricted):
+ (JSC::JSArray::tryCreate):
+ (JSC::constructArray):
+ (JSC::constructArrayNegativeIndexed):
+ (JSC::JSArray::tryCreateForInitializationPrivate): Deleted.
+ (JSC::createArrayButterfly): Deleted.
+ * runtime/JSCellInlines.h:
+ (JSC::allocateCell):
+ * runtime/JSObject.h:
+ (JSC::JSObject::initializeIndex):
+ (JSC::JSObject::initializeIndexWithoutBarrier):
+ * runtime/ObjectInitializationScope.cpp: Added.
+ (JSC::ObjectInitializationScope::ObjectInitializationScope):
+ (JSC::ObjectInitializationScope::~ObjectInitializationScope):
+ (JSC::ObjectInitializationScope::notifyAllocated):
+ (JSC::ObjectInitializationScope::verifyPropertiesAreInitialized):
+ * runtime/ObjectInitializationScope.h: Added.
+ (JSC::ObjectInitializationScope::ObjectInitializationScope):
+ (JSC::ObjectInitializationScope::vm):
+ (JSC::ObjectInitializationScope::notifyAllocated):
+ * runtime/Operations.h:
+ (JSC::isScribbledValue):
+ (JSC::scribble):
+ * runtime/RegExpMatchesArray.cpp:
+ (JSC::createEmptyRegExpMatchesArray):
+ * runtime/RegExpMatchesArray.h:
+ (JSC::tryCreateUninitializedRegExpMatchesArray):
+ (JSC::createRegExpMatchesArray):
+ * runtime/VMEntryScope.cpp:
+ (JSC::VMEntryScope::VMEntryScope):
+
2017-04-27 Carlos Garcia Campos <cgar...@igalia.com>
[GTK] Remote inspector should support inspecting targets with previous version of backend commands
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (215884 => 215885)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2017-04-27 19:24:07 UTC (rev 215885)
@@ -2445,11 +2445,16 @@
FE3A06BF1C11041600390FDD /* JITRightShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */; };
FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */; };
FE4238901BE18C3C00514737 /* JITSubGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */; };
+ FE48E6381EB118D2005D7A96 /* ObjectInitializationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE48E6361EB1188F005D7A96 /* ObjectInitializationScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FE48E6391EB118D9005D7A96 /* ObjectInitializationScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE48E6371EB118AD005D7A96 /* ObjectInitializationScope.cpp */; };
FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
FE4D55B81AE716CA0052E459 /* IterationStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4D55B71AE716CA0052E459 /* IterationStatus.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE5068651AE246390009DAB7 /* DeferredSourceDump.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5068641AE246390009DAB7 /* DeferredSourceDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE5068671AE25E280009DAB7 /* DeferredSourceDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */; };
+ FE54DEFB1E8C6D8800A892C5 /* DisallowVMReentry.h in Headers */ = {isa = PBXBuildFile; fileRef = FE54DEFA1E8C6D7200A892C5 /* DisallowVMReentry.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ FE54DEFD1E8C6E3700A892C5 /* DisallowVMReentry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE54DEFC1E8C6DFF00A892C5 /* DisallowVMReentry.cpp */; };
+ FE54DEFF1E8D76FA00A892C5 /* DisallowScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE54DEFE1E8D742800A892C5 /* DisallowScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
FE5628CD1E99512D00C49E45 /* AirPrintSpecial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */; };
FE5628CE1E99513200C49E45 /* AirPrintSpecial.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */; };
FE5932A7183C5A2600A1ECCC /* VMEntryScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */; };
@@ -5080,11 +5085,16 @@
FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITRightShiftGenerator.cpp; sourceTree = "<group>"; };
FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITRightShiftGenerator.h; sourceTree = "<group>"; };
FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITSubGenerator.cpp; sourceTree = "<group>"; };
+ FE48E6361EB1188F005D7A96 /* ObjectInitializationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectInitializationScope.h; sourceTree = "<group>"; };
+ FE48E6371EB118AD005D7A96 /* ObjectInitializationScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectInitializationScope.cpp; sourceTree = "<group>"; };
FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionOverrides.h; sourceTree = "<group>"; };
FE4D55B71AE716CA0052E459 /* IterationStatus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IterationStatus.h; sourceTree = "<group>"; };
FE5068641AE246390009DAB7 /* DeferredSourceDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeferredSourceDump.h; sourceTree = "<group>"; };
FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredSourceDump.cpp; sourceTree = "<group>"; };
+ FE54DEFA1E8C6D7200A892C5 /* DisallowVMReentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisallowVMReentry.h; sourceTree = "<group>"; };
+ FE54DEFC1E8C6DFF00A892C5 /* DisallowVMReentry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisallowVMReentry.cpp; sourceTree = "<group>"; };
+ FE54DEFE1E8D742800A892C5 /* DisallowScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisallowScope.h; sourceTree = "<group>"; };
FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirPrintSpecial.cpp; path = b3/air/AirPrintSpecial.cpp; sourceTree = "<group>"; };
FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirPrintSpecial.h; path = b3/air/AirPrintSpecial.h; sourceTree = "<group>"; };
FE5932A5183C5A2600A1ECCC /* VMEntryScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMEntryScope.cpp; sourceTree = "<group>"; };
@@ -6562,6 +6572,9 @@
0FE0500E1AA9091100D33B33 /* DirectArgumentsOffset.h */,
14386A721DD69895008652C4 /* DirectEvalExecutable.cpp */,
14386A731DD69895008652C4 /* DirectEvalExecutable.h */,
+ FE54DEFE1E8D742800A892C5 /* DisallowScope.h */,
+ FE54DEFC1E8C6DFF00A892C5 /* DisallowVMReentry.cpp */,
+ FE54DEFA1E8C6D7200A892C5 /* DisallowVMReentry.h */,
A70447EB17A0BD7000F5898E /* DumpContext.cpp */,
A70447EC17A0BD7000F5898E /* DumpContext.h */,
FE318FDD1CAC8C5300DFCC54 /* ECMAScriptSpecInternalFunctions.cpp */,
@@ -6891,6 +6904,8 @@
142D3938103E4560007DCB52 /* NumericStrings.h */,
BC2680C60E16D4E900A06E92 /* ObjectConstructor.cpp */,
BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */,
+ FE48E6371EB118AD005D7A96 /* ObjectInitializationScope.cpp */,
+ FE48E6361EB1188F005D7A96 /* ObjectInitializationScope.h */,
BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */,
BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */,
F692A8770255597D01FF60F7 /* Operations.cpp */,
@@ -8133,6 +8148,7 @@
5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */,
0FEC856E1BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h in Headers */,
0FEC85701BDACDC70080FF74 /* AirArg.h in Headers */,
+ FE48E6381EB118D2005D7A96 /* ObjectInitializationScope.h in Headers */,
0F64EAF31C4ECD0600621E9B /* AirArgInlines.h in Headers */,
0FEC85721BDACDC70080FF74 /* AirBasicBlock.h in Headers */,
0FB3878E1BFBC44D00E3AB1E /* AirBlockWorklist.h in Headers */,
@@ -8184,6 +8200,7 @@
79ABB17E1E5CCB570045B9A6 /* AirDisassembler.h in Headers */,
53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */,
BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
+ FE54DEFF1E8D76FA00A892C5 /* DisallowScope.h in Headers */,
0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
79A228361D35D71F00D8E067 /* ArithProfile.h in Headers */,
0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
@@ -9498,6 +9515,7 @@
AD2FCC181DB59CB200B3E736 /* WebAssemblyInstanceConstructor.lut.h in Headers */,
AD2FCBF31DB58DAD00B3E736 /* WebAssemblyInstancePrototype.h in Headers */,
AD2FCC191DB59CB200B3E736 /* WebAssemblyInstancePrototype.lut.h in Headers */,
+ FE54DEFB1E8C6D8800A892C5 /* DisallowVMReentry.h in Headers */,
ADE8029A1E08F1DE0058DE78 /* WebAssemblyLinkErrorConstructor.h in Headers */,
7965C2171E5D799600B7591D /* AirAllocateRegistersByGraphColoring.h in Headers */,
ADE8029C1E08F1DE0058DE78 /* WebAssemblyLinkErrorPrototype.h in Headers */,
@@ -10048,6 +10066,7 @@
0FEC857B1BDACDC70080FF74 /* AirHandleCalleeSaves.cpp in Sources */,
0FEC857D1BDACDC70080FF74 /* AirInsertionSet.cpp in Sources */,
0FEC857F1BDACDC70080FF74 /* AirInst.cpp in Sources */,
+ FE48E6391EB118D9005D7A96 /* ObjectInitializationScope.cpp in Sources */,
0FDF67D61D9DC440001B9825 /* AirKind.cpp in Sources */,
0FE34C191C4B39AE0003A512 /* AirLogRegisterPressure.cpp in Sources */,
0F61832E1C45BF070072450B /* AirLowerAfterRegAlloc.cpp in Sources */,
@@ -10476,6 +10495,7 @@
142E3135134FF0A600AFADB5 /* HandleSet.cpp in Sources */,
142E3137134FF0A600AFADB5 /* HandleStack.cpp in Sources */,
79A0907F1D768465008B889B /* HashMapImpl.cpp in Sources */,
+ FE54DEFD1E8C6E3700A892C5 /* DisallowVMReentry.cpp in Sources */,
14BA7A9713AADFF8005B7C2C /* Heap.cpp in Sources */,
DC3D2B0C1D34377000BA918C /* HeapCell.cpp in Sources */,
0F32BD101BB34F190093A57F /* HeapHelperPool.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1438,7 +1438,7 @@
exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
CallFrame::argumentOffset(0);
for (unsigned i = length; i--;)
- result->initializeIndex(vm, i, arguments[i].jsValue());
+ result->putDirectIndex(exec, i, arguments[i].jsValue());
return result;
@@ -2085,7 +2085,7 @@
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
- JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, structure, length);
+ JSArray* result = JSArray::tryCreate(vm, structure, length);
if (UNLIKELY(!result)) {
throwOutOfMemoryError(exec, scope);
return nullptr;
@@ -2098,12 +2098,12 @@
if (JSFixedArray* array = jsDynamicCast<JSFixedArray*>(vm, value)) {
// We are spreading.
for (unsigned i = 0; i < array->size(); i++) {
- result->initializeIndex(vm, index, array->get(i));
+ result->putDirectIndex(exec, index, array->get(i));
++index;
}
} else {
// We are not spreading.
- result->initializeIndex(vm, index, value);
+ result->putDirectIndex(exec, index, value);
++index;
}
}
Modified: trunk/Source/_javascript_Core/ftl/FTLOperations.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/ftl/FTLOperations.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/ftl/FTLOperations.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -352,7 +352,7 @@
unsigned index = property.location().info();
if (index >= length)
continue;
- result->initializeIndex(vm, index, JSValue::decode(values[i]));
+ result->putDirectIndex(exec, index, JSValue::decode(values[i]));
}
return result;
@@ -364,9 +364,9 @@
ASSERT(argumentCount > 0);
unsigned arraySize = (argumentCount - 1) > numberOfArgumentsToSkip ? argumentCount - 1 - numberOfArgumentsToSkip : 0;
- // FIXME: we should throw an out of memory error here if tryCreateForInitializationPrivate() fails.
+ // FIXME: we should throw an out of memory error here if tryCreate() fails.
// https://bugs.webkit.org/show_bug.cgi?id=169784
- JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, structure, arraySize);
+ JSArray* array = JSArray::tryCreate(vm, structure, arraySize);
RELEASE_ASSERT(array);
for (unsigned i = materialization->properties().size(); i--;) {
@@ -380,7 +380,7 @@
unsigned arrayIndex = argIndex - numberOfArgumentsToSkip;
if (arrayIndex >= arraySize)
continue;
- array->initializeIndex(vm, arrayIndex, JSValue::decode(values[i]));
+ array->putDirectIndex(exec, arrayIndex, JSValue::decode(values[i]));
}
#if !ASSERT_DISABLED
@@ -455,10 +455,10 @@
}
}
- // FIXME: we should throw an out of memory error here if checkedArraySize has hasOverflowed() or tryCreateForInitializationPrivate() fails.
+ // FIXME: we should throw an out of memory error here if checkedArraySize has hasOverflowed() or tryCreate() fails.
// https://bugs.webkit.org/show_bug.cgi?id=169784
unsigned arraySize = checkedArraySize.unsafeGet(); // Crashes if overflowed.
- JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, structure, arraySize);
+ JSArray* result = JSArray::tryCreate(vm, structure, arraySize);
RELEASE_ASSERT(result);
#if !ASSERT_DISABLED
@@ -493,12 +493,12 @@
if (JSFixedArray* fixedArray = jsDynamicCast<JSFixedArray*>(vm, value)) {
for (unsigned i = 0; i < fixedArray->size(); i++) {
ASSERT(fixedArray->get(i));
- result->initializeIndex(vm, arrayIndex, fixedArray->get(i));
+ result->putDirectIndex(exec, arrayIndex, fixedArray->get(i));
++arrayIndex;
}
} else {
// We are not spreading.
- result->initializeIndex(vm, arrayIndex, value);
+ result->putDirectIndex(exec, arrayIndex, value);
++arrayIndex;
}
}
Modified: trunk/Source/_javascript_Core/heap/DeferGC.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/heap/DeferGC.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/heap/DeferGC.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-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
@@ -31,7 +31,7 @@
namespace JSC {
#ifndef NDEBUG
-WTF::ThreadSpecificKey DisallowGC::s_isGCDisallowedOnCurrentThread = 0;
+WTF::ThreadSpecificKey DisallowGC::s_scopeReentryCount = 0;
#endif
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/DeferGC.h (215884 => 215885)
--- trunk/Source/_javascript_Core/heap/DeferGC.h 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/heap/DeferGC.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -25,6 +25,7 @@
#pragma once
+#include "DisallowScope.h"
#include "Heap.h"
#include <wtf/Noncopyable.h>
#include <wtf/ThreadSpecific.h>
@@ -67,41 +68,41 @@
Heap& m_heap;
};
-class DisallowGC {
+class DisallowGC : public DisallowScope<DisallowGC> {
WTF_MAKE_NONCOPYABLE(DisallowGC);
+ typedef DisallowScope<DisallowGC> Base;
public:
- DisallowGC()
- {
-#ifndef NDEBUG
- WTF::threadSpecificSet(s_isGCDisallowedOnCurrentThread, reinterpret_cast<void*>(true));
-#endif
- }
+#ifdef NDEBUG
- ~DisallowGC()
+ ALWAYS_INLINE DisallowGC(bool = false) { }
+ ALWAYS_INLINE static void initialize() { }
+
+#else // not NDEBUG
+
+ DisallowGC(bool enabled = true)
+ : Base(enabled)
+ { }
+
+ static void initialize()
{
-#ifndef NDEBUG
- WTF::threadSpecificSet(s_isGCDisallowedOnCurrentThread, reinterpret_cast<void*>(false));
-#endif
+ WTF::threadSpecificKeyCreate(&s_scopeReentryCount, 0);
}
- static bool isGCDisallowedOnCurrentThread()
+private:
+ static uintptr_t scopeReentryCount()
{
-#ifndef NDEBUG
- return !!WTF::threadSpecificGet(s_isGCDisallowedOnCurrentThread);
-#else
- return false;
-#endif
+ return reinterpret_cast<uintptr_t>(WTF::threadSpecificGet(s_scopeReentryCount));
}
- static void initialize()
+ static void setScopeReentryCount(uintptr_t value)
{
-#ifndef NDEBUG
- WTF::threadSpecificKeyCreate(&s_isGCDisallowedOnCurrentThread, 0);
-#endif
+ WTF::threadSpecificSet(s_scopeReentryCount, reinterpret_cast<void*>(value));
}
+
+ JS_EXPORT_PRIVATE static WTF::ThreadSpecificKey s_scopeReentryCount;
-#ifndef NDEBUG
- JS_EXPORT_PRIVATE static WTF::ThreadSpecificKey s_isGCDisallowedOnCurrentThread;
-#endif
+#endif // NDEBUG
+
+ friend class DisallowScope<DisallowGC>;
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h (215884 => 215885)
--- trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/heap/GCDeferralContextInlines.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-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
@@ -37,7 +37,7 @@
ALWAYS_INLINE GCDeferralContext::~GCDeferralContext()
{
- ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
+ ASSERT(!DisallowGC::isInEffectOnCurrentThread());
#if ENABLE(GC_VALIDATION)
ASSERT(!m_heap.vm()->isInitializingObject());
#endif
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -2454,7 +2454,7 @@
void Heap::collectIfNecessaryOrDefer(GCDeferralContext* deferralContext)
{
- ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
+ ASSERT(deferralContext || isDeferred() || !DisallowGC::isInEffectOnCurrentThread());
if (!m_isSafeToCollect)
return;
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1314,7 +1314,8 @@
return JSValue::encode(jsNull());
ASSERT(!lexicalGlobalObject->isHavingABadTime());
- JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, resultStructure, resultSize);
+ ObjectInitializationScope initializationScope(vm);
+ JSArray* result = JSArray::tryCreateUninitializedRestricted(initializationScope, resultStructure, resultSize);
if (UNLIKELY(!result)) {
throwOutOfMemoryError(exec, scope);
return encodedJSValue();
Modified: trunk/Source/_javascript_Core/runtime/ClonedArguments.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/ClonedArguments.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/ClonedArguments.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -87,8 +87,6 @@
ClonedArguments* ClonedArguments::createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
{
- VM& vm = myFrame->vm();
-
JSFunction* callee;
if (inlineCallFrame)
@@ -110,13 +108,13 @@
result = createEmpty(myFrame, callee, length);
for (unsigned i = length; i--;)
- result->initializeIndex(vm, i, inlineCallFrame->arguments[i + 1].recover(targetFrame));
+ result->putDirectIndex(myFrame, i, inlineCallFrame->arguments[i + 1].recover(targetFrame));
} else {
length = targetFrame->argumentCount();
result = createEmpty(myFrame, callee, length);
for (unsigned i = length; i--;)
- result->initializeIndex(vm, i, targetFrame->uncheckedArgument(i));
+ result->putDirectIndex(myFrame, i, targetFrame->uncheckedArgument(i));
}
break;
}
@@ -127,7 +125,7 @@
} }
ASSERT(myFrame->lexicalGlobalObject()->clonedArgumentsStructure() == result->structure());
- ASSERT(!result->structure(vm)->needsSlowPutIndexing() || shouldUseSlowPut(result->structure(vm)->indexingType()));
+ ASSERT(!result->structure()->needsSlowPutIndexing() || shouldUseSlowPut(result->structure()->indexingType()));
return result;
}
@@ -146,7 +144,7 @@
ClonedArguments* result = createEmpty(vm, structure, callee, length);
for (unsigned i = length; i--;)
- result->initializeIndex(vm, i, argumentStart[i].jsValue());
+ result->putDirectIndex(exec, i, argumentStart[i].jsValue());
ASSERT(!result->structure(vm)->needsSlowPutIndexing() || shouldUseSlowPut(result->structure(vm)->indexingType()));
return result;
}
Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1009,7 +1009,7 @@
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
- JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, structure, arraySize);
+ JSArray* result = JSArray::tryCreate(vm, structure, arraySize);
if (UNLIKELY(!result))
THROW(createOutOfMemoryError(exec));
CHECK_EXCEPTION();
@@ -1022,12 +1022,12 @@
JSFixedArray* array = jsCast<JSFixedArray*>(value);
for (unsigned i = 0; i < array->size(); i++) {
RELEASE_ASSERT(array->get(i));
- result->initializeIndex(vm, index, array->get(i));
+ result->putDirectIndex(exec, index, array->get(i));
++index;
}
} else {
// We are not spreading.
- result->initializeIndex(vm, index, value);
+ result->putDirectIndex(exec, index, value);
++index;
}
}
Added: trunk/Source/_javascript_Core/runtime/DisallowScope.h (0 => 215885)
--- trunk/Source/_javascript_Core/runtime/DisallowScope.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/DisallowScope.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -0,0 +1,87 @@
+/*
+ * 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 <wtf/Noncopyable.h>
+
+namespace JSC {
+
+template<class T>
+class DisallowScope {
+ WTF_MAKE_NONCOPYABLE(DisallowScope);
+public:
+#ifdef NDEBUG
+
+ ALWAYS_INLINE DisallowScope(bool = false) { }
+ ALWAYS_INLINE ~DisallowScope() { }
+ ALWAYS_INLINE static bool isInEffectOnCurrentThread() { return false; }
+ ALWAYS_INLINE void enable() { }
+
+#else // not NDEBUG
+
+ DisallowScope(bool enabled = true)
+ {
+ m_isEnabled = enabled;
+ if (m_isEnabled)
+ enterScope();
+ }
+
+ ~DisallowScope()
+ {
+ if (m_isEnabled)
+ exitScope();
+ }
+
+ static bool isInEffectOnCurrentThread()
+ {
+ return !!T::scopeReentryCount();
+ }
+
+ void enable()
+ {
+ m_isEnabled = true;
+ enterScope();
+ }
+
+private:
+ void enterScope()
+ {
+ auto count = T::scopeReentryCount();
+ T::setScopeReentryCount(++count);
+ }
+
+ void exitScope()
+ {
+ auto count = T::scopeReentryCount();
+ ASSERT(count);
+ T::setScopeReentryCount(--count);
+ }
+
+ bool m_isEnabled;
+#endif // NDEBUG
+};
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/DisallowVMReentry.cpp (0 => 215885)
--- trunk/Source/_javascript_Core/runtime/DisallowVMReentry.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/DisallowVMReentry.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -0,0 +1,37 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DisallowVMReentry.h"
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+#ifndef NDEBUG
+WTF::ThreadSpecificKey DisallowVMReentry::s_scopeReentryCount = 0;
+#endif
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/DisallowVMReentry.h (0 => 215885)
--- trunk/Source/_javascript_Core/runtime/DisallowVMReentry.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/DisallowVMReentry.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -0,0 +1,70 @@
+/*
+ * 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 "DisallowScope.h"
+#include <wtf/ThreadSpecific.h>
+
+namespace JSC {
+
+class DisallowVMReentry : public DisallowScope<DisallowVMReentry> {
+ WTF_MAKE_NONCOPYABLE(DisallowVMReentry);
+ typedef DisallowScope<DisallowVMReentry> Base;
+public:
+#ifdef NDEBUG
+
+ ALWAYS_INLINE DisallowVMReentry(bool = false) { }
+ ALWAYS_INLINE static void initialize() { }
+
+#else // not NDEBUG
+
+ DisallowVMReentry(bool enabled = true)
+ : Base(enabled)
+ { }
+
+ static void initialize()
+ {
+ WTF::threadSpecificKeyCreate(&s_scopeReentryCount, 0);
+ }
+
+private:
+ static uintptr_t scopeReentryCount()
+ {
+ return reinterpret_cast<uintptr_t>(WTF::threadSpecificGet(s_scopeReentryCount));
+ }
+ static void setScopeReentryCount(uintptr_t value)
+ {
+ WTF::threadSpecificSet(s_scopeReentryCount, reinterpret_cast<void*>(value));
+ }
+
+ JS_EXPORT_PRIVATE static WTF::ThreadSpecificKey s_scopeReentryCount;
+
+#endif // NDEBUG
+
+ friend class DisallowScope<DisallowVMReentry>;
+};
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -29,6 +29,7 @@
#include "config.h"
#include "InitializeThreading.h"
+#include "DisallowVMReentry.h"
#include "ExecutableAllocator.h"
#include "Heap.h"
#include "Identifier.h"
@@ -71,6 +72,7 @@
LLInt::initialize();
#ifndef NDEBUG
DisallowGC::initialize();
+ DisallowVMReentry::initialize();
#endif
initializeSuperSampler();
WTFThreadData& threadData = wtfThreadData();
Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/JSArray.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -60,11 +60,15 @@
return butterfly;
}
-JSArray* JSArray::tryCreateForInitializationPrivate(VM& vm, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
+JSArray* JSArray::tryCreateUninitializedRestricted(ObjectInitializationScope& scope, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
{
+ VM& vm = scope.vm();
+
if (UNLIKELY(initialLength > MAX_STORAGE_VECTOR_LENGTH))
return 0;
+ JSGlobalObject* globalObject = structure->globalObject();
+ bool createUninitialized = globalObject->isOriginalArrayStructure(structure);
unsigned outOfLineStorage = structure->outOfLineCapacity();
Butterfly* butterfly;
@@ -83,29 +87,34 @@
butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage);
butterfly->setVectorLength(vectorLength);
butterfly->setPublicLength(initialLength);
+ unsigned i = (createUninitialized ? initialLength : 0);
if (hasDouble(indexingType)) {
- for (unsigned i = initialLength; i < vectorLength; ++i)
+ for (; i < vectorLength; ++i)
butterfly->contiguousDouble()[i] = PNaN;
} else {
- for (unsigned i = initialLength; i < vectorLength; ++i)
+ for (; i < vectorLength; ++i)
butterfly->contiguous()[i].clear();
}
} else {
- unsigned vectorLength = ArrayStorage::optimalVectorLength(0, structure, initialLength);
- void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength)));
+ static const unsigned indexBias = 0;
+ unsigned vectorLength = ArrayStorage::optimalVectorLength(indexBias, structure, initialLength);
+ void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(indexBias, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength)));
if (UNLIKELY(!temp))
return nullptr;
- butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage);
+ butterfly = Butterfly::fromBase(temp, indexBias, outOfLineStorage);
*butterfly->indexingHeader() = indexingHeaderForArrayStorage(initialLength, vectorLength);
ArrayStorage* storage = butterfly->arrayStorage();
- storage->m_indexBias = 0;
+ storage->m_indexBias = indexBias;
storage->m_sparseMap.clear();
storage->m_numValuesInVector = initialLength;
- for (unsigned i = initialLength; i < vectorLength; ++i)
+ unsigned i = (createUninitialized ? initialLength : 0);
+ for (; i < vectorLength; ++i)
storage->m_vector[i].clear();
}
- return createWithButterfly(vm, deferralContext, structure, butterfly);
+ JSArray* result = createWithButterfly(vm, deferralContext, structure, butterfly);
+ scope.notifyAllocated(result, createUninitialized);
+ return result;
}
void JSArray::setLengthWritable(ExecState* exec, bool writable)
@@ -873,7 +882,8 @@
return nullptr;
ASSERT(!lexicalGlobalObject->isHavingABadTime());
- JSArray* resultArray = JSArray::tryCreateForInitializationPrivate(vm, resultStructure, count);
+ ObjectInitializationScope scope(vm);
+ JSArray* resultArray = JSArray::tryCreateUninitializedRestricted(scope, resultStructure, count);
if (UNLIKELY(!resultArray))
return nullptr;
Modified: trunk/Source/_javascript_Core/runtime/JSArray.h (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/JSArray.h 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/JSArray.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -56,18 +56,24 @@
static JSArray* create(VM&, Structure*, unsigned initialLength = 0);
static JSArray* createWithButterfly(VM&, GCDeferralContext*, Structure*, Butterfly*);
- // tryCreateForInitializationPrivate is used for fast construction of arrays whose size and
- // contents are known at time of creation. This should be considered a private API.
+ // tryCreateUninitializedRestricted is used for fast construction of arrays whose size and
+ // contents are known at time of creation. This is a restricted API for careful use only in
+ // performance critical code paths. If you don't have a good reason to use it, you probably
+ // shouldn't use it. Instead, you should go with
+ // - JSArray::tryCreate() or JSArray::create() instead of tryCreateUninitializedRestricted(), and
+ // - putDirectIndex() instead of initializeIndex().
+ //
// Clients of this interface must:
// - null-check the result (indicating out of memory, or otherwise unable to allocate vector).
// - call 'initializeIndex' for all properties in sequence, for 0 <= i < initialLength.
// - Provide a valid GCDefferalContext* if they might garbage collect when initializing properties,
// otherwise the caller can provide a null GCDefferalContext*.
+ // - Provide a local stack instance of ObjectInitializationScope at the call site.
//
- JS_EXPORT_PRIVATE static JSArray* tryCreateForInitializationPrivate(VM&, GCDeferralContext*, Structure*, unsigned initialLength);
- static JSArray* tryCreateForInitializationPrivate(VM& vm, Structure* structure, unsigned initialLength)
+ JS_EXPORT_PRIVATE static JSArray* tryCreateUninitializedRestricted(ObjectInitializationScope&, GCDeferralContext*, Structure*, unsigned initialLength);
+ static JSArray* tryCreateUninitializedRestricted(ObjectInitializationScope& scope, Structure* structure, unsigned initialLength)
{
- return tryCreateForInitializationPrivate(vm, nullptr, structure, initialLength);
+ return tryCreateUninitializedRestricted(scope, nullptr, structure, initialLength);
}
JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool throwException);
@@ -204,13 +210,6 @@
return butterfly;
}
-inline Butterfly* createArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned initialLength)
-{
- Butterfly* result = tryCreateArrayButterfly(vm, intendedOwner, initialLength);
- RELEASE_ASSERT(result);
- return result;
-}
-
Butterfly* createArrayButterflyInDictionaryIndexingMode(
VM&, JSCell* intendedOwner, unsigned initialLength);
@@ -227,8 +226,8 @@
|| hasDouble(indexingType)
|| hasContiguous(indexingType));
- if (initialLength > MAX_STORAGE_VECTOR_LENGTH)
- return 0;
+ if (UNLIKELY(initialLength > MAX_STORAGE_VECTOR_LENGTH))
+ return nullptr;
unsigned vectorLength = Butterfly::optimalContiguousVectorLength(structure, initialLength);
void* temp = vm.auxiliarySpace.tryAllocate(nullptr, Butterfly::totalSize(0, outOfLineStorage, true, vectorLength * sizeof(EncodedJSValue)));
@@ -245,7 +244,7 @@
ASSERT(
indexingType == ArrayWithSlowPutArrayStorage
|| indexingType == ArrayWithArrayStorage);
- butterfly = tryCreateArrayButterfly(vm, 0, initialLength);
+ butterfly = tryCreateArrayButterfly(vm, nullptr, initialLength);
if (!butterfly)
return nullptr;
for (unsigned i = 0; i < BASE_ARRAY_STORAGE_VECTOR_LEN; ++i)
@@ -295,7 +294,8 @@
{
VM& vm = exec->vm();
unsigned length = values.size();
- JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, arrayStructure, length);
+ ObjectInitializationScope scope(vm);
+ JSArray* array = JSArray::tryCreateUninitializedRestricted(scope, arrayStructure, length);
// FIXME: we should probably throw an out of memory error here, but
// when making this change we should check that all clients of this
@@ -304,7 +304,7 @@
RELEASE_ASSERT(array);
for (unsigned i = 0; i < length; ++i)
- array->initializeIndex(vm, i, values.at(i));
+ array->initializeIndex(scope, i, values.at(i));
return array;
}
@@ -311,7 +311,8 @@
inline JSArray* constructArray(ExecState* exec, Structure* arrayStructure, const JSValue* values, unsigned length)
{
VM& vm = exec->vm();
- JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, arrayStructure, length);
+ ObjectInitializationScope scope(vm);
+ JSArray* array = JSArray::tryCreateUninitializedRestricted(scope, arrayStructure, length);
// FIXME: we should probably throw an out of memory error here, but
// when making this change we should check that all clients of this
@@ -320,7 +321,7 @@
RELEASE_ASSERT(array);
for (unsigned i = 0; i < length; ++i)
- array->initializeIndex(vm, i, values[i]);
+ array->initializeIndex(scope, i, values[i]);
return array;
}
@@ -327,7 +328,8 @@
inline JSArray* constructArrayNegativeIndexed(ExecState* exec, Structure* arrayStructure, const JSValue* values, unsigned length)
{
VM& vm = exec->vm();
- JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, arrayStructure, length);
+ ObjectInitializationScope scope(vm);
+ JSArray* array = JSArray::tryCreateUninitializedRestricted(scope, arrayStructure, length);
// FIXME: we should probably throw an out of memory error here, but
// when making this change we should check that all clients of this
@@ -336,7 +338,7 @@
RELEASE_ASSERT(array);
for (int i = 0; i < static_cast<int>(length); ++i)
- array->initializeIndex(vm, i, values[-i]);
+ array->initializeIndex(scope, i, values[-i]);
return array;
}
Modified: trunk/Source/_javascript_Core/runtime/JSCellInlines.h (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/JSCellInlines.h 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/JSCellInlines.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -145,7 +145,7 @@
template<typename T>
void* allocateCell(Heap& heap, size_t size)
{
- ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
+ ASSERT(!DisallowGC::isInEffectOnCurrentThread());
ASSERT(size >= sizeof(T));
JSCell* result = static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(size));
#if ENABLE(GC_VALIDATION)
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -36,6 +36,7 @@
#include "Heap.h"
#include "IndexingHeaderInlines.h"
#include "JSCell.h"
+#include "ObjectInitializationScope.h"
#include "PropertySlot.h"
#include "PropertyStorage.h"
#include "PutDirectIndexMode.h"
@@ -420,15 +421,16 @@
}
}
- void initializeIndex(VM& vm, unsigned i, JSValue v)
+ void initializeIndex(ObjectInitializationScope& scope, unsigned i, JSValue v)
{
- initializeIndex(vm, i, v, indexingType());
+ initializeIndex(scope, i, v, indexingType());
}
// NOTE: Clients of this method may call it more than once for any index, and this is supposed
// to work.
- ALWAYS_INLINE void initializeIndex(VM& vm, unsigned i, JSValue v, IndexingType indexingType)
+ ALWAYS_INLINE void initializeIndex(ObjectInitializationScope& scope, unsigned i, JSValue v, IndexingType indexingType)
{
+ VM& vm = scope.vm();
Butterfly* butterfly = m_butterfly.get();
switch (indexingType) {
case ALL_UNDECIDED_INDEXING_TYPES: {
@@ -477,14 +479,14 @@
}
}
- void initializeIndexWithoutBarrier(unsigned i, JSValue v)
+ void initializeIndexWithoutBarrier(ObjectInitializationScope& scope, unsigned i, JSValue v)
{
- initializeIndexWithoutBarrier(i, v, indexingType());
+ initializeIndexWithoutBarrier(scope, i, v, indexingType());
}
// This version of initializeIndex is for cases where you know that you will not need any
// barriers. This implies not having any data format conversions.
- ALWAYS_INLINE void initializeIndexWithoutBarrier(unsigned i, JSValue v, IndexingType indexingType)
+ ALWAYS_INLINE void initializeIndexWithoutBarrier(ObjectInitializationScope&, unsigned i, JSValue v, IndexingType indexingType)
{
Butterfly* butterfly = m_butterfly.get();
switch (indexingType) {
Added: trunk/Source/_javascript_Core/runtime/ObjectInitializationScope.cpp (0 => 215885)
--- trunk/Source/_javascript_Core/runtime/ObjectInitializationScope.cpp (rev 0)
+++ trunk/Source/_javascript_Core/runtime/ObjectInitializationScope.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -0,0 +1,78 @@
+/*
+ * 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 "ObjectInitializationScope.h"
+
+#include "JSObject.h"
+#include "Operations.h"
+
+namespace JSC {
+
+#ifndef NDEBUG
+ObjectInitializationScope::ObjectInitializationScope(VM& vm)
+ : m_vm(vm)
+ , m_disallowGC(false)
+ , m_disallowVMReentry(false)
+{
+}
+
+ObjectInitializationScope::~ObjectInitializationScope()
+{
+ if (!m_object)
+ return;
+ verifyPropertiesAreInitialized(m_object);
+}
+
+void ObjectInitializationScope::notifyAllocated(JSObject* object, bool wasCreatedUninitialized)
+{
+ if (wasCreatedUninitialized) {
+ m_disallowGC.enable();
+ m_disallowVMReentry.enable();
+ m_object = object;
+ } else
+ verifyPropertiesAreInitialized(object);
+}
+
+void ObjectInitializationScope::verifyPropertiesAreInitialized(JSObject* object)
+{
+ Butterfly* butterfly = object->butterfly();
+ IndexingType indexingType = object->structure(m_vm)->indexingType();
+ unsigned vectorLength = butterfly->vectorLength();
+ if (UNLIKELY(hasUndecided(indexingType))) {
+ // Nothing to verify.
+ } else if (LIKELY(!hasAnyArrayStorage(indexingType))) {
+ auto data = ""
+ for (unsigned i = 0; i < vectorLength; ++i)
+ ASSERT(!isScribbledValue(data[i].get()));
+ } else {
+ ArrayStorage* storage = butterfly->arrayStorage();
+ for (unsigned i = 0; i < vectorLength; ++i)
+ ASSERT(!isScribbledValue(storage->m_vector[i].get()));
+ }
+}
+#endif
+
+} // namespace JSC
Added: trunk/Source/_javascript_Core/runtime/ObjectInitializationScope.h (0 => 215885)
--- trunk/Source/_javascript_Core/runtime/ObjectInitializationScope.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/ObjectInitializationScope.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -0,0 +1,72 @@
+/*
+ * 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 "DeferGC.h"
+#include "DisallowVMReentry.h"
+
+namespace JSC {
+
+class VM;
+class JSObject;
+
+#ifdef NDEBUG
+
+class ObjectInitializationScope {
+public:
+ ALWAYS_INLINE ObjectInitializationScope(VM& vm)
+ : m_vm(vm)
+ { }
+
+ ALWAYS_INLINE VM& vm() const { return m_vm; }
+ ALWAYS_INLINE void notifyAllocated(JSObject*, bool) { }
+
+private:
+ VM& m_vm;
+};
+
+#else // not NDEBUG
+
+class ObjectInitializationScope {
+public:
+ JS_EXPORT_PRIVATE ObjectInitializationScope(VM&);
+ JS_EXPORT_PRIVATE ~ObjectInitializationScope();
+
+ VM& vm() const { return m_vm; }
+ void notifyAllocated(JSObject*, bool wasCreatedUninitialized);
+
+private:
+ void verifyPropertiesAreInitialized(JSObject*);
+
+ VM& m_vm;
+ DisallowGC m_disallowGC;
+ DisallowVMReentry m_disallowVMReentry;
+ JSObject* m_object { nullptr };
+};
+
+#endif // NDEBUG
+
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/Operations.h (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/Operations.h 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/Operations.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 1999-2000 Harri Porten (por...@kde.org)
- * Copyright (C) 2002, 2005-2009, 2013-2014, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2002-2017 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -261,12 +261,18 @@
return !ASSERT_DISABLED || Options::scribbleFreeCells();
}
+#define SCRIBBLE_WORD static_cast<intptr_t>(0xbadbeef0)
+
+inline bool isScribbledValue(JSValue value)
+{
+ return JSValue::encode(value) == JSValue::encode(bitwise_cast<JSCell*>(SCRIBBLE_WORD));
+}
+
inline void scribble(void* base, size_t size)
{
for (size_t i = size / sizeof(EncodedJSValue); i--;) {
// Use a 16-byte aligned value to ensure that it passes the cell check.
- static_cast<EncodedJSValue*>(base)[i] = JSValue::encode(
- bitwise_cast<JSCell*>(static_cast<intptr_t>(0xbadbeef0)));
+ static_cast<EncodedJSValue*>(base)[i] = JSValue::encode(bitwise_cast<JSCell*>(SCRIBBLE_WORD));
}
}
Modified: trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-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
@@ -39,7 +39,8 @@
GCDeferralContext deferralContext(vm.heap);
if (UNLIKELY(globalObject->isHavingABadTime())) {
- array = JSArray::tryCreateForInitializationPrivate(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
+ ObjectInitializationScope scope(vm);
+ array = JSArray::tryCreateUninitializedRestricted(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
// FIXME: we should probably throw an out of memory error here, but
// when making this change we should check that all clients of this
// function will correctly handle an exception being thrown from here.
@@ -46,21 +47,22 @@
// https://bugs.webkit.org/show_bug.cgi?id=169786
RELEASE_ASSERT(array);
- array->initializeIndexWithoutBarrier(0, jsEmptyString(&vm));
+ array->initializeIndexWithoutBarrier(scope, 0, jsEmptyString(&vm));
if (unsigned numSubpatterns = regExp->numSubpatterns()) {
for (unsigned i = 1; i <= numSubpatterns; ++i)
- array->initializeIndexWithoutBarrier(i, jsUndefined());
+ array->initializeIndexWithoutBarrier(scope, i, jsUndefined());
}
} else {
- array = tryCreateUninitializedRegExpMatchesArray(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
+ ObjectInitializationScope scope(vm);
+ array = tryCreateUninitializedRegExpMatchesArray(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
RELEASE_ASSERT(array);
- array->initializeIndexWithoutBarrier(0, jsEmptyString(&vm), ArrayWithContiguous);
+ array->initializeIndexWithoutBarrier(scope, 0, jsEmptyString(&vm), ArrayWithContiguous);
if (unsigned numSubpatterns = regExp->numSubpatterns()) {
for (unsigned i = 1; i <= numSubpatterns; ++i)
- array->initializeIndexWithoutBarrier(i, jsUndefined(), ArrayWithContiguous);
+ array->initializeIndexWithoutBarrier(scope, i, jsUndefined(), ArrayWithContiguous);
}
}
Modified: trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/RegExpMatchesArray.h 2017-04-27 19:24:07 UTC (rev 215885)
@@ -32,23 +32,29 @@
static const PropertyOffset RegExpMatchesArrayIndexPropertyOffset = 100;
static const PropertyOffset RegExpMatchesArrayInputPropertyOffset = 101;
-ALWAYS_INLINE JSArray* tryCreateUninitializedRegExpMatchesArray(VM& vm, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
+ALWAYS_INLINE JSArray* tryCreateUninitializedRegExpMatchesArray(ObjectInitializationScope& scope, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
{
+ VM& vm = scope.vm();
unsigned vectorLength = initialLength;
if (vectorLength > MAX_STORAGE_VECTOR_LENGTH)
return 0;
+ JSGlobalObject* globalObject = structure->globalObject();
+ bool createUninitialized = globalObject->isOriginalArrayStructure(structure);
void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
- if (!temp)
+ if (UNLIKELY(!temp))
return nullptr;
Butterfly* butterfly = Butterfly::fromBase(temp, 0, structure->outOfLineCapacity());
butterfly->setVectorLength(vectorLength);
butterfly->setPublicLength(initialLength);
-
- for (unsigned i = initialLength; i < vectorLength; ++i)
+
+ unsigned i = (createUninitialized ? initialLength : 0);
+ for (; i < vectorLength; ++i)
butterfly->contiguous()[i].clear();
-
- return JSArray::createWithButterfly(vm, deferralContext, structure, butterfly);
+
+ JSArray* result = JSArray::createWithButterfly(vm, deferralContext, structure, butterfly);
+ scope.notifyAllocated(result, createUninitialized);
+ return result;
}
ALWAYS_INLINE JSArray* createRegExpMatchesArray(
@@ -80,7 +86,8 @@
GCDeferralContext deferralContext(vm.heap);
if (UNLIKELY(globalObject->isHavingABadTime())) {
- array = JSArray::tryCreateForInitializationPrivate(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
+ ObjectInitializationScope scope(vm);
+ array = JSArray::tryCreateUninitializedRestricted(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
// FIXME: we should probably throw an out of memory error here, but
// when making this change we should check that all clients of this
// function will correctly handle an exception being thrown from here.
@@ -89,7 +96,7 @@
setProperties();
- array->initializeIndexWithoutBarrier(0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start));
+ array->initializeIndexWithoutBarrier(scope, 0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start));
for (unsigned i = 1; i <= numSubpatterns; ++i) {
int start = subpatternResults[2 * i];
@@ -98,10 +105,11 @@
value = JSRopeString::createSubstringOfResolved(vm, &deferralContext, input, start, subpatternResults[2 * i + 1] - start);
else
value = jsUndefined();
- array->initializeIndexWithoutBarrier(i, value);
+ array->initializeIndexWithoutBarrier(scope, i, value);
}
} else {
- array = tryCreateUninitializedRegExpMatchesArray(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
+ ObjectInitializationScope scope(vm);
+ array = tryCreateUninitializedRegExpMatchesArray(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
RELEASE_ASSERT(array);
setProperties();
@@ -108,7 +116,7 @@
// Now the object is safe to scan by GC.
- array->initializeIndexWithoutBarrier(0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start), ArrayWithContiguous);
+ array->initializeIndexWithoutBarrier(scope, 0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start), ArrayWithContiguous);
for (unsigned i = 1; i <= numSubpatterns; ++i) {
int start = subpatternResults[2 * i];
@@ -117,7 +125,7 @@
value = JSRopeString::createSubstringOfResolved(vm, &deferralContext, input, start, subpatternResults[2 * i + 1] - start);
else
value = jsUndefined();
- array->initializeIndexWithoutBarrier(i, value, ArrayWithContiguous);
+ array->initializeIndexWithoutBarrier(scope, i, value, ArrayWithContiguous);
}
}
return array;
Modified: trunk/Source/_javascript_Core/runtime/VMEntryScope.cpp (215884 => 215885)
--- trunk/Source/_javascript_Core/runtime/VMEntryScope.cpp 2017-04-27 19:08:22 UTC (rev 215884)
+++ trunk/Source/_javascript_Core/runtime/VMEntryScope.cpp 2017-04-27 19:24:07 UTC (rev 215885)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-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 @@
#include "config.h"
#include "VMEntryScope.h"
+#include "DisallowVMReentry.h"
#include "Options.h"
#include "SamplingProfiler.h"
#include "VM.h"
@@ -39,6 +40,7 @@
: m_vm(vm)
, m_globalObject(globalObject)
{
+ ASSERT(!DisallowVMReentry::isInEffectOnCurrentThread());
ASSERT(wtfThreadData().stack().isGrowingDownward());
if (!vm.entryScope) {
vm.entryScope = this;