Changeset 215885 in webkit


Ignore:
Timestamp:
Apr 27, 2017 12:24:07 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

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:

  1. the client should not re-enter the VM to execute JS code, and
  2. 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.
  1. 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.

  1. Factored a DisallowScope out of DisallowGC, and make DisallowGC extend it. Introduce a DisallowVMReentry class that extends DisallowScope.
  1. 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.

  1. 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:
  • JavaScriptCore.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):

Location:
trunk/Source/JavaScriptCore
Files:
5 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r215843 r215885  
    714714    runtime/DirectArgumentsOffset.cpp
    715715    runtime/DirectEvalExecutable.cpp
     716    runtime/DisallowVMReentry.cpp
    716717    runtime/DumpContext.cpp
    717718    runtime/ECMAScriptSpecInternalFunctions.cpp
     
    853854    runtime/NumberPrototype.cpp
    854855    runtime/ObjectConstructor.cpp
     856    runtime/ObjectInitializationScope.cpp
    855857    runtime/ObjectPrototype.cpp
    856858    runtime/Operations.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r215862 r215885  
     12017-04-27  Mark Lam  <mark.lam@apple.com>
     2
     3        Audit and fix incorrect uses of JSArray::tryCreateForInitializationPrivate().
     4        https://bugs.webkit.org/show_bug.cgi?id=171344
     5        <rdar://problem/31352667>
     6
     7        Reviewed by Filip Pizlo.
     8
     9        JSArray::tryCreateForInitializationPrivate() should only be used in performance
     10        critical paths, and should always be used with care because it creates an
     11        uninitialized object that needs to be initialized by its client before the object
     12        can be released into the system.  Before the object is fully initialized:
     13        a. the client should not re-enter the VM to execute JS code, and
     14        b. GC should not run.
     15
     16        This is because until the object is fully initialized, it is an inconsistent
     17        state that the GC and JS code will not be happy about.
     18
     19        In this patch, we do the following:
     20
     21        1. Renamed JSArray::tryCreateForInitializationPrivate() to
     22           JSArray::tryCreateUninitializedRestricted() because "private" is a bit ambiguous
     23           and can be confused with APIs that are called freely within WebKit but are
     24           not meant for clients of WebKit.  In this case, we intend for use of this API
     25           to be restricted to only a few carefully considered and crafted cases.
     26
     27        2. Introduce the ObjectInitializationScope RAII object which covers the period
     28           when the uninitialized object is created and gets initialized.
     29
     30           ObjectInitializationScope will asserts that either the object is created
     31           fully initialized (in the case where the object structure is not an "original"
     32           structure) or if created uninitialized, is fully initialized at the end of
     33           the scope.
     34
     35           If the object is created uninitialized, the ObjectInitializationScope also
     36           ensures that we do not GC nor re-enter the VM to execute JS code.  This is
     37           achieved by enabling DisallowGC and DisallowVMReentry scopes.
     38
     39           tryCreateUninitializedRestricted() and initializeIndex() now requires an
     40           ObjectInitializationScope instance.  The ObjectInitializationScope replaces
     41           the VM& argument because it can be used to pass the VM& itself.  This is a
     42           small optimization that makes passing the ObjectInitializationScope free even
     43           on release builds.
     44
     45        3. Factored a DisallowScope out of DisallowGC, and make DisallowGC extend it.
     46           Introduce a DisallowVMReentry class that extends DisallowScope.
     47
     48        4. Fixed a bug found by the ObjectInitializationScope.  The bug is that there are
     49           scenarios where the structure passed to tryCreateUninitializedRestricted()
     50           that may not be an "original" structure.  As a result, initializeIndex() would
     51           end up allocating new structures, and therefore trigger a GC.
     52
     53           The fix is to detect that the structure passed to tryCreateUninitializedRestricted()
     54           is not an "original" one, and pre-initialize the array with 0s.
     55
     56           This bug was detected by existing tests. Hence, no new test needed.
     57
     58        5. Replaced all inappropriate uses of tryCreateUninitializedRestricted() with
     59           tryCreate().  Inappropriate uses here means code that is not in performance
     60           critical paths.
     61
     62           Similarly, replaced accompanying uses of initializeIndex() with putDirectIndex().
     63
     64           This patch is performance neutral (according to the JSC command line benchmarks).
     65
     66        * CMakeLists.txt:
     67        * JavaScriptCore.xcodeproj/project.pbxproj:
     68        * dfg/DFGOperations.cpp:
     69        * ftl/FTLOperations.cpp:
     70        (JSC::FTL::operationMaterializeObjectInOSR):
     71        * heap/DeferGC.cpp:
     72        * heap/DeferGC.h:
     73        (JSC::DisallowGC::DisallowGC):
     74        (JSC::DisallowGC::initialize):
     75        (JSC::DisallowGC::scopeReentryCount):
     76        (JSC::DisallowGC::setScopeReentryCount):
     77        (JSC::DisallowGC::~DisallowGC): Deleted.
     78        (JSC::DisallowGC::isGCDisallowedOnCurrentThread): Deleted.
     79        * heap/GCDeferralContextInlines.h:
     80        (JSC::GCDeferralContext::~GCDeferralContext):
     81        * heap/Heap.cpp:
     82        (JSC::Heap::collectIfNecessaryOrDefer):
     83        * runtime/ArrayPrototype.cpp:
     84        (JSC::arrayProtoPrivateFuncConcatMemcpy):
     85        * runtime/ClonedArguments.cpp:
     86        (JSC::ClonedArguments::createWithInlineFrame):
     87        (JSC::ClonedArguments::createByCopyingFrom):
     88        * runtime/CommonSlowPaths.cpp:
     89        (JSC::SLOW_PATH_DECL):
     90        * runtime/DisallowScope.h: Added.
     91        (JSC::DisallowScope::DisallowScope):
     92        (JSC::DisallowScope::~DisallowScope):
     93        (JSC::DisallowScope::isInEffectOnCurrentThread):
     94        (JSC::DisallowScope::enable):
     95        (JSC::DisallowScope::enterScope):
     96        (JSC::DisallowScope::exitScope):
     97        * runtime/DisallowVMReentry.cpp: Added.
     98        * runtime/DisallowVMReentry.h: Added.
     99        (JSC::DisallowVMReentry::DisallowVMReentry):
     100        (JSC::DisallowVMReentry::initialize):
     101        (JSC::DisallowVMReentry::scopeReentryCount):
     102        (JSC::DisallowVMReentry::setScopeReentryCount):
     103        * runtime/InitializeThreading.cpp:
     104        (JSC::initializeThreading):
     105        * runtime/JSArray.cpp:
     106        (JSC::JSArray::tryCreateUninitializedRestricted):
     107        (JSC::JSArray::fastSlice):
     108        (JSC::JSArray::tryCreateForInitializationPrivate): Deleted.
     109        * runtime/JSArray.h:
     110        (JSC::JSArray::tryCreateUninitializedRestricted):
     111        (JSC::JSArray::tryCreate):
     112        (JSC::constructArray):
     113        (JSC::constructArrayNegativeIndexed):
     114        (JSC::JSArray::tryCreateForInitializationPrivate): Deleted.
     115        (JSC::createArrayButterfly): Deleted.
     116        * runtime/JSCellInlines.h:
     117        (JSC::allocateCell):
     118        * runtime/JSObject.h:
     119        (JSC::JSObject::initializeIndex):
     120        (JSC::JSObject::initializeIndexWithoutBarrier):
     121        * runtime/ObjectInitializationScope.cpp: Added.
     122        (JSC::ObjectInitializationScope::ObjectInitializationScope):
     123        (JSC::ObjectInitializationScope::~ObjectInitializationScope):
     124        (JSC::ObjectInitializationScope::notifyAllocated):
     125        (JSC::ObjectInitializationScope::verifyPropertiesAreInitialized):
     126        * runtime/ObjectInitializationScope.h: Added.
     127        (JSC::ObjectInitializationScope::ObjectInitializationScope):
     128        (JSC::ObjectInitializationScope::vm):
     129        (JSC::ObjectInitializationScope::notifyAllocated):
     130        * runtime/Operations.h:
     131        (JSC::isScribbledValue):
     132        (JSC::scribble):
     133        * runtime/RegExpMatchesArray.cpp:
     134        (JSC::createEmptyRegExpMatchesArray):
     135        * runtime/RegExpMatchesArray.h:
     136        (JSC::tryCreateUninitializedRegExpMatchesArray):
     137        (JSC::createRegExpMatchesArray):
     138        * runtime/VMEntryScope.cpp:
     139        (JSC::VMEntryScope::VMEntryScope):
     140
    11412017-04-27  Carlos Garcia Campos  <cgarcia@igalia.com>
    2142
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r215843 r215885  
    24462446                FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */; };
    24472447                FE4238901BE18C3C00514737 /* JITSubGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */; };
     2448                FE48E6381EB118D2005D7A96 /* ObjectInitializationScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE48E6361EB1188F005D7A96 /* ObjectInitializationScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2449                FE48E6391EB118D9005D7A96 /* ObjectInitializationScope.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE48E6371EB118AD005D7A96 /* ObjectInitializationScope.cpp */; };
    24482450                FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
    24492451                FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
     
    24512453                FE5068651AE246390009DAB7 /* DeferredSourceDump.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5068641AE246390009DAB7 /* DeferredSourceDump.h */; settings = {ATTRIBUTES = (Private, ); }; };
    24522454                FE5068671AE25E280009DAB7 /* DeferredSourceDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */; };
     2455                FE54DEFB1E8C6D8800A892C5 /* DisallowVMReentry.h in Headers */ = {isa = PBXBuildFile; fileRef = FE54DEFA1E8C6D7200A892C5 /* DisallowVMReentry.h */; settings = {ATTRIBUTES = (Private, ); }; };
     2456                FE54DEFD1E8C6E3700A892C5 /* DisallowVMReentry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE54DEFC1E8C6DFF00A892C5 /* DisallowVMReentry.cpp */; };
     2457                FE54DEFF1E8D76FA00A892C5 /* DisallowScope.h in Headers */ = {isa = PBXBuildFile; fileRef = FE54DEFE1E8D742800A892C5 /* DisallowScope.h */; settings = {ATTRIBUTES = (Private, ); }; };
    24532458                FE5628CD1E99512D00C49E45 /* AirPrintSpecial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */; };
    24542459                FE5628CE1E99513200C49E45 /* AirPrintSpecial.h in Headers */ = {isa = PBXBuildFile; fileRef = FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */; };
     
    50815086                FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITRightShiftGenerator.h; sourceTree = "<group>"; };
    50825087                FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITSubGenerator.cpp; sourceTree = "<group>"; };
     5088                FE48E6361EB1188F005D7A96 /* ObjectInitializationScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjectInitializationScope.h; sourceTree = "<group>"; };
     5089                FE48E6371EB118AD005D7A96 /* ObjectInitializationScope.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectInitializationScope.cpp; sourceTree = "<group>"; };
    50835090                FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
    50845091                FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionOverrides.h; sourceTree = "<group>"; };
     
    50865093                FE5068641AE246390009DAB7 /* DeferredSourceDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeferredSourceDump.h; sourceTree = "<group>"; };
    50875094                FE5068661AE25E280009DAB7 /* DeferredSourceDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferredSourceDump.cpp; sourceTree = "<group>"; };
     5095                FE54DEFA1E8C6D7200A892C5 /* DisallowVMReentry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisallowVMReentry.h; sourceTree = "<group>"; };
     5096                FE54DEFC1E8C6DFF00A892C5 /* DisallowVMReentry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisallowVMReentry.cpp; sourceTree = "<group>"; };
     5097                FE54DEFE1E8D742800A892C5 /* DisallowScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisallowScope.h; sourceTree = "<group>"; };
    50885098                FE5628CB1E99512400C49E45 /* AirPrintSpecial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirPrintSpecial.cpp; path = b3/air/AirPrintSpecial.cpp; sourceTree = "<group>"; };
    50895099                FE5628CC1E99512400C49E45 /* AirPrintSpecial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirPrintSpecial.h; path = b3/air/AirPrintSpecial.h; sourceTree = "<group>"; };
     
    65636573                                14386A721DD69895008652C4 /* DirectEvalExecutable.cpp */,
    65646574                                14386A731DD69895008652C4 /* DirectEvalExecutable.h */,
     6575                                FE54DEFE1E8D742800A892C5 /* DisallowScope.h */,
     6576                                FE54DEFC1E8C6DFF00A892C5 /* DisallowVMReentry.cpp */,
     6577                                FE54DEFA1E8C6D7200A892C5 /* DisallowVMReentry.h */,
    65656578                                A70447EB17A0BD7000F5898E /* DumpContext.cpp */,
    65666579                                A70447EC17A0BD7000F5898E /* DumpContext.h */,
     
    68926905                                BC2680C60E16D4E900A06E92 /* ObjectConstructor.cpp */,
    68936906                                BC2680C70E16D4E900A06E92 /* ObjectConstructor.h */,
     6907                                FE48E6371EB118AD005D7A96 /* ObjectInitializationScope.cpp */,
     6908                                FE48E6361EB1188F005D7A96 /* ObjectInitializationScope.h */,
    68946909                                BC2680C80E16D4E900A06E92 /* ObjectPrototype.cpp */,
    68956910                                BC2680C90E16D4E900A06E92 /* ObjectPrototype.h */,
     
    81348149                                0FEC856E1BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h in Headers */,
    81358150                                0FEC85701BDACDC70080FF74 /* AirArg.h in Headers */,
     8151                                FE48E6381EB118D2005D7A96 /* ObjectInitializationScope.h in Headers */,
    81368152                                0F64EAF31C4ECD0600621E9B /* AirArgInlines.h in Headers */,
    81378153                                0FEC85721BDACDC70080FF74 /* AirBasicBlock.h in Headers */,
     
    81858201                                53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */,
    81868202                                BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
     8203                                FE54DEFF1E8D76FA00A892C5 /* DisallowScope.h in Headers */,
    81878204                                0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
    81888205                                79A228361D35D71F00D8E067 /* ArithProfile.h in Headers */,
     
    94999516                                AD2FCBF31DB58DAD00B3E736 /* WebAssemblyInstancePrototype.h in Headers */,
    95009517                                AD2FCC191DB59CB200B3E736 /* WebAssemblyInstancePrototype.lut.h in Headers */,
     9518                                FE54DEFB1E8C6D8800A892C5 /* DisallowVMReentry.h in Headers */,
    95019519                                ADE8029A1E08F1DE0058DE78 /* WebAssemblyLinkErrorConstructor.h in Headers */,
    95029520                                7965C2171E5D799600B7591D /* AirAllocateRegistersByGraphColoring.h in Headers */,
     
    1004910067                                0FEC857D1BDACDC70080FF74 /* AirInsertionSet.cpp in Sources */,
    1005010068                                0FEC857F1BDACDC70080FF74 /* AirInst.cpp in Sources */,
     10069                                FE48E6391EB118D9005D7A96 /* ObjectInitializationScope.cpp in Sources */,
    1005110070                                0FDF67D61D9DC440001B9825 /* AirKind.cpp in Sources */,
    1005210071                                0FE34C191C4B39AE0003A512 /* AirLogRegisterPressure.cpp in Sources */,
     
    1047710496                                142E3137134FF0A600AFADB5 /* HandleStack.cpp in Sources */,
    1047810497                                79A0907F1D768465008B889B /* HashMapImpl.cpp in Sources */,
     10498                                FE54DEFD1E8C6E3700A892C5 /* DisallowVMReentry.cpp in Sources */,
    1047910499                                14BA7A9713AADFF8005B7C2C /* Heap.cpp in Sources */,
    1048010500                                DC3D2B0C1D34377000BA918C /* HeapCell.cpp in Sources */,
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r215779 r215885  
    14391439        CallFrame::argumentOffset(0);
    14401440    for (unsigned i = length; i--;)
    1441         result->initializeIndex(vm, i, arguments[i].jsValue());
     1441        result->putDirectIndex(exec, i, arguments[i].jsValue());
    14421442
    14431443   
     
    20862086    Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
    20872087
    2088     JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, structure, length);
     2088    JSArray* result = JSArray::tryCreate(vm, structure, length);
    20892089    if (UNLIKELY(!result)) {
    20902090        throwOutOfMemoryError(exec, scope);
     
    20992099            // We are spreading.
    21002100            for (unsigned i = 0; i < array->size(); i++) {
    2101                 result->initializeIndex(vm, index, array->get(i));
     2101                result->putDirectIndex(exec, index, array->get(i));
    21022102                ++index;
    21032103            }
    21042104        } else {
    21052105            // We are not spreading.
    2106             result->initializeIndex(vm, index, value);
     2106            result->putDirectIndex(exec, index, value);
    21072107            ++index;
    21082108        }
  • trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp

    r214313 r215885  
    353353                if (index >= length)
    354354                    continue;
    355                 result->initializeIndex(vm, index, JSValue::decode(values[i]));
     355                result->putDirectIndex(exec, index, JSValue::decode(values[i]));
    356356            }
    357357           
     
    365365            unsigned arraySize = (argumentCount - 1) > numberOfArgumentsToSkip ? argumentCount - 1 - numberOfArgumentsToSkip : 0;
    366366
    367             // FIXME: we should throw an out of memory error here if tryCreateForInitializationPrivate() fails.
     367            // FIXME: we should throw an out of memory error here if tryCreate() fails.
    368368            // https://bugs.webkit.org/show_bug.cgi?id=169784
    369             JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, structure, arraySize);
     369            JSArray* array = JSArray::tryCreate(vm, structure, arraySize);
    370370            RELEASE_ASSERT(array);
    371371
     
    381381                if (arrayIndex >= arraySize)
    382382                    continue;
    383                 array->initializeIndex(vm, arrayIndex, JSValue::decode(values[i]));
     383                array->putDirectIndex(exec, arrayIndex, JSValue::decode(values[i]));
    384384            }
    385385
     
    456456        }
    457457
    458         // FIXME: we should throw an out of memory error here if checkedArraySize has hasOverflowed() or tryCreateForInitializationPrivate() fails.
     458        // FIXME: we should throw an out of memory error here if checkedArraySize has hasOverflowed() or tryCreate() fails.
    459459        // https://bugs.webkit.org/show_bug.cgi?id=169784
    460460        unsigned arraySize = checkedArraySize.unsafeGet(); // Crashes if overflowed.
    461         JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, structure, arraySize);
     461        JSArray* result = JSArray::tryCreate(vm, structure, arraySize);
    462462        RELEASE_ASSERT(result);
    463463
     
    494494                for (unsigned i = 0; i < fixedArray->size(); i++) {
    495495                    ASSERT(fixedArray->get(i));
    496                     result->initializeIndex(vm, arrayIndex, fixedArray->get(i));
     496                    result->putDirectIndex(exec, arrayIndex, fixedArray->get(i));
    497497                    ++arrayIndex;
    498498                }
    499499            } else {
    500500                // We are not spreading.
    501                 result->initializeIndex(vm, arrayIndex, value);
     501                result->putDirectIndex(exec, arrayIndex, value);
    502502                ++arrayIndex;
    503503            }
  • trunk/Source/JavaScriptCore/heap/DeferGC.cpp

    r163844 r215885  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3232
    3333#ifndef NDEBUG
    34 WTF::ThreadSpecificKey DisallowGC::s_isGCDisallowedOnCurrentThread = 0;
     34WTF::ThreadSpecificKey DisallowGC::s_scopeReentryCount = 0;
    3535#endif
    3636
  • trunk/Source/JavaScriptCore/heap/DeferGC.h

    r210553 r215885  
    2626#pragma once
    2727
     28#include "DisallowScope.h"
    2829#include "Heap.h"
    2930#include <wtf/Noncopyable.h>
     
    6869};
    6970
    70 class DisallowGC {
     71class DisallowGC : public DisallowScope<DisallowGC> {
    7172    WTF_MAKE_NONCOPYABLE(DisallowGC);
     73    typedef DisallowScope<DisallowGC> Base;
    7274public:
    73     DisallowGC()
     75#ifdef NDEBUG
     76
     77    ALWAYS_INLINE DisallowGC(bool = false) { }
     78    ALWAYS_INLINE static void initialize() { }
     79
     80#else // not NDEBUG
     81
     82    DisallowGC(bool enabled = true)
     83        : Base(enabled)
     84    { }
     85
     86    static void initialize()
    7487    {
    75 #ifndef NDEBUG
    76         WTF::threadSpecificSet(s_isGCDisallowedOnCurrentThread, reinterpret_cast<void*>(true));
    77 #endif
     88        WTF::threadSpecificKeyCreate(&s_scopeReentryCount, 0);
    7889    }
    7990
    80     ~DisallowGC()
     91private:
     92    static uintptr_t scopeReentryCount()
    8193    {
    82 #ifndef NDEBUG
    83         WTF::threadSpecificSet(s_isGCDisallowedOnCurrentThread, reinterpret_cast<void*>(false));
    84 #endif
     94        return reinterpret_cast<uintptr_t>(WTF::threadSpecificGet(s_scopeReentryCount));
    8595    }
     96    static void setScopeReentryCount(uintptr_t value)
     97    {
     98        WTF::threadSpecificSet(s_scopeReentryCount, reinterpret_cast<void*>(value));
     99    }
     100   
     101    JS_EXPORT_PRIVATE static WTF::ThreadSpecificKey s_scopeReentryCount;
    86102
    87     static bool isGCDisallowedOnCurrentThread()
    88     {
    89 #ifndef NDEBUG
    90         return !!WTF::threadSpecificGet(s_isGCDisallowedOnCurrentThread);
    91 #else
    92         return false;
    93 #endif
    94     }
    95     static void initialize()
    96     {
    97 #ifndef NDEBUG
    98         WTF::threadSpecificKeyCreate(&s_isGCDisallowedOnCurrentThread, 0);
    99 #endif
    100     }
    101 
    102 #ifndef NDEBUG
    103     JS_EXPORT_PRIVATE static WTF::ThreadSpecificKey s_isGCDisallowedOnCurrentThread;
    104 #endif
     103#endif // NDEBUG
     104   
     105    friend class DisallowScope<DisallowGC>;
    105106};
    106107
  • trunk/Source/JavaScriptCore/heap/GCDeferralContextInlines.h

    r206555 r215885  
    11/*
    2  * Copyright (C) 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3838ALWAYS_INLINE GCDeferralContext::~GCDeferralContext()
    3939{
    40     ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
     40    ASSERT(!DisallowGC::isInEffectOnCurrentThread());
    4141#if ENABLE(GC_VALIDATION)
    4242    ASSERT(!m_heap.vm()->isInitializingObject());
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r215340 r215885  
    24552455void Heap::collectIfNecessaryOrDefer(GCDeferralContext* deferralContext)
    24562456{
    2457     ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
     2457    ASSERT(deferralContext || isDeferred() || !DisallowGC::isInEffectOnCurrentThread());
    24582458
    24592459    if (!m_isSafeToCollect)
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r215768 r215885  
    13151315
    13161316    ASSERT(!lexicalGlobalObject->isHavingABadTime());
    1317     JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, resultStructure, resultSize);
     1317    ObjectInitializationScope initializationScope(vm);
     1318    JSArray* result = JSArray::tryCreateUninitializedRestricted(initializationScope, resultStructure, resultSize);
    13181319    if (UNLIKELY(!result)) {
    13191320        throwOutOfMemoryError(exec, scope);
  • trunk/Source/JavaScriptCore/runtime/ClonedArguments.cpp

    r210844 r215885  
    8888ClonedArguments* ClonedArguments::createWithInlineFrame(ExecState* myFrame, ExecState* targetFrame, InlineCallFrame* inlineCallFrame, ArgumentsMode mode)
    8989{
    90     VM& vm = myFrame->vm();
    91    
    9290    JSFunction* callee;
    9391   
     
    111109
    112110            for (unsigned i = length; i--;)
    113                 result->initializeIndex(vm, i, inlineCallFrame->arguments[i + 1].recover(targetFrame));
     111                result->putDirectIndex(myFrame, i, inlineCallFrame->arguments[i + 1].recover(targetFrame));
    114112        } else {
    115113            length = targetFrame->argumentCount();
     
    117115
    118116            for (unsigned i = length; i--;)
    119                 result->initializeIndex(vm, i, targetFrame->uncheckedArgument(i));
     117                result->putDirectIndex(myFrame, i, targetFrame->uncheckedArgument(i));
    120118        }
    121119        break;
     
    128126
    129127    ASSERT(myFrame->lexicalGlobalObject()->clonedArgumentsStructure() == result->structure());
    130     ASSERT(!result->structure(vm)->needsSlowPutIndexing() || shouldUseSlowPut(result->structure(vm)->indexingType()));
     128    ASSERT(!result->structure()->needsSlowPutIndexing() || shouldUseSlowPut(result->structure()->indexingType()));
    131129    return result;
    132130}
     
    147145   
    148146    for (unsigned i = length; i--;)
    149         result->initializeIndex(vm, i, argumentStart[i].jsValue());
     147        result->putDirectIndex(exec, i, argumentStart[i].jsValue());
    150148    ASSERT(!result->structure(vm)->needsSlowPutIndexing() || shouldUseSlowPut(result->structure(vm)->indexingType()));
    151149    return result;
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r215779 r215885  
    10101010    Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
    10111011
    1012     JSArray* result = JSArray::tryCreateForInitializationPrivate(vm, structure, arraySize);
     1012    JSArray* result = JSArray::tryCreate(vm, structure, arraySize);
    10131013    if (UNLIKELY(!result))
    10141014        THROW(createOutOfMemoryError(exec));
     
    10231023            for (unsigned i = 0; i < array->size(); i++) {
    10241024                RELEASE_ASSERT(array->get(i));
    1025                 result->initializeIndex(vm, index, array->get(i));
     1025                result->putDirectIndex(exec, index, array->get(i));
    10261026                ++index;
    10271027            }
    10281028        } else {
    10291029            // We are not spreading.
    1030             result->initializeIndex(vm, index, value);
     1030            result->putDirectIndex(exec, index, value);
    10311031            ++index;
    10321032        }
  • trunk/Source/JavaScriptCore/runtime/InitializeThreading.cpp

    r215340 r215885  
    3030#include "InitializeThreading.h"
    3131
     32#include "DisallowVMReentry.h"
    3233#include "ExecutableAllocator.h"
    3334#include "Heap.h"
     
    7273#ifndef NDEBUG
    7374        DisallowGC::initialize();
     75        DisallowVMReentry::initialize();
    7476#endif
    7577        initializeSuperSampler();
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r215777 r215885  
    6161}
    6262
    63 JSArray* JSArray::tryCreateForInitializationPrivate(VM& vm, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
    64 {
     63JSArray* JSArray::tryCreateUninitializedRestricted(ObjectInitializationScope& scope, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
     64{
     65    VM& vm = scope.vm();
     66
    6567    if (UNLIKELY(initialLength > MAX_STORAGE_VECTOR_LENGTH))
    6668        return 0;
    6769
     70    JSGlobalObject* globalObject = structure->globalObject();
     71    bool createUninitialized = globalObject->isOriginalArrayStructure(structure);
    6872    unsigned outOfLineStorage = structure->outOfLineCapacity();
    6973
     
    8488        butterfly->setVectorLength(vectorLength);
    8589        butterfly->setPublicLength(initialLength);
     90        unsigned i = (createUninitialized ? initialLength : 0);
    8691        if (hasDouble(indexingType)) {
    87             for (unsigned i = initialLength; i < vectorLength; ++i)
     92            for (; i < vectorLength; ++i)
    8893                butterfly->contiguousDouble()[i] = PNaN;
    8994        } else {
    90             for (unsigned i = initialLength; i < vectorLength; ++i)
     95            for (; i < vectorLength; ++i)
    9196                butterfly->contiguous()[i].clear();
    9297        }
    9398    } else {
    94         unsigned vectorLength = ArrayStorage::optimalVectorLength(0, structure, initialLength);
    95         void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength)));
     99        static const unsigned indexBias = 0;
     100        unsigned vectorLength = ArrayStorage::optimalVectorLength(indexBias, structure, initialLength);
     101        void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(indexBias, outOfLineStorage, true, ArrayStorage::sizeFor(vectorLength)));
    96102        if (UNLIKELY(!temp))
    97103            return nullptr;
    98         butterfly = Butterfly::fromBase(temp, 0, outOfLineStorage);
     104        butterfly = Butterfly::fromBase(temp, indexBias, outOfLineStorage);
    99105        *butterfly->indexingHeader() = indexingHeaderForArrayStorage(initialLength, vectorLength);
    100106        ArrayStorage* storage = butterfly->arrayStorage();
    101         storage->m_indexBias = 0;
     107        storage->m_indexBias = indexBias;
    102108        storage->m_sparseMap.clear();
    103109        storage->m_numValuesInVector = initialLength;
    104         for (unsigned i = initialLength; i < vectorLength; ++i)
     110        unsigned i = (createUninitialized ? initialLength : 0);
     111        for (; i < vectorLength; ++i)
    105112            storage->m_vector[i].clear();
    106113    }
    107114
    108     return createWithButterfly(vm, deferralContext, structure, butterfly);
     115    JSArray* result = createWithButterfly(vm, deferralContext, structure, butterfly);
     116    scope.notifyAllocated(result, createUninitialized);
     117    return result;
    109118}
    110119
     
    874883
    875884        ASSERT(!lexicalGlobalObject->isHavingABadTime());
    876         JSArray* resultArray = JSArray::tryCreateForInitializationPrivate(vm, resultStructure, count);
     885        ObjectInitializationScope scope(vm);
     886        JSArray* resultArray = JSArray::tryCreateUninitializedRestricted(scope, resultStructure, count);
    877887        if (UNLIKELY(!resultArray))
    878888            return nullptr;
  • trunk/Source/JavaScriptCore/runtime/JSArray.h

    r215777 r215885  
    5757    static JSArray* createWithButterfly(VM&, GCDeferralContext*, Structure*, Butterfly*);
    5858
    59     // tryCreateForInitializationPrivate is used for fast construction of arrays whose size and
    60     // contents are known at time of creation. This should be considered a private API.
     59    // tryCreateUninitializedRestricted is used for fast construction of arrays whose size and
     60    // contents are known at time of creation. This is a restricted API for careful use only in
     61    // performance critical code paths. If you don't have a good reason to use it, you probably
     62    // shouldn't use it. Instead, you should go with
     63    //   - JSArray::tryCreate() or JSArray::create() instead of tryCreateUninitializedRestricted(), and
     64    //   - putDirectIndex() instead of initializeIndex().
     65    //
    6166    // Clients of this interface must:
    6267    //   - null-check the result (indicating out of memory, or otherwise unable to allocate vector).
     
    6469    //   - Provide a valid GCDefferalContext* if they might garbage collect when initializing properties,
    6570    //     otherwise the caller can provide a null GCDefferalContext*.
     71    //   - Provide a local stack instance of ObjectInitializationScope at the call site.
    6672    //
    67     JS_EXPORT_PRIVATE static JSArray* tryCreateForInitializationPrivate(VM&, GCDeferralContext*, Structure*, unsigned initialLength);
    68     static JSArray* tryCreateForInitializationPrivate(VM& vm, Structure* structure, unsigned initialLength)
    69     {
    70         return tryCreateForInitializationPrivate(vm, nullptr, structure, initialLength);
     73    JS_EXPORT_PRIVATE static JSArray* tryCreateUninitializedRestricted(ObjectInitializationScope&, GCDeferralContext*, Structure*, unsigned initialLength);
     74    static JSArray* tryCreateUninitializedRestricted(ObjectInitializationScope& scope, Structure* structure, unsigned initialLength)
     75    {
     76        return tryCreateUninitializedRestricted(scope, nullptr, structure, initialLength);
    7177    }
    7278
     
    205211}
    206212
    207 inline Butterfly* createArrayButterfly(VM& vm, JSCell* intendedOwner, unsigned initialLength)
    208 {
    209     Butterfly* result = tryCreateArrayButterfly(vm, intendedOwner, initialLength);
    210     RELEASE_ASSERT(result);
    211     return result;
    212 }
    213 
    214213Butterfly* createArrayButterflyInDictionaryIndexingMode(
    215214    VM&, JSCell* intendedOwner, unsigned initialLength);
     
    228227            || hasContiguous(indexingType));
    229228
    230         if (initialLength > MAX_STORAGE_VECTOR_LENGTH)
    231             return 0;
     229        if (UNLIKELY(initialLength > MAX_STORAGE_VECTOR_LENGTH))
     230            return nullptr;
    232231
    233232        unsigned vectorLength = Butterfly::optimalContiguousVectorLength(structure, initialLength);
     
    246245            indexingType == ArrayWithSlowPutArrayStorage
    247246            || indexingType == ArrayWithArrayStorage);
    248         butterfly = tryCreateArrayButterfly(vm, 0, initialLength);
     247        butterfly = tryCreateArrayButterfly(vm, nullptr, initialLength);
    249248        if (!butterfly)
    250249            return nullptr;
     
    296295    VM& vm = exec->vm();
    297296    unsigned length = values.size();
    298     JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, arrayStructure, length);
     297    ObjectInitializationScope scope(vm);
     298    JSArray* array = JSArray::tryCreateUninitializedRestricted(scope, arrayStructure, length);
    299299
    300300    // FIXME: we should probably throw an out of memory error here, but
     
    305305
    306306    for (unsigned i = 0; i < length; ++i)
    307         array->initializeIndex(vm, i, values.at(i));
     307        array->initializeIndex(scope, i, values.at(i));
    308308    return array;
    309309}
     
    312312{
    313313    VM& vm = exec->vm();
    314     JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, arrayStructure, length);
     314    ObjectInitializationScope scope(vm);
     315    JSArray* array = JSArray::tryCreateUninitializedRestricted(scope, arrayStructure, length);
    315316
    316317    // FIXME: we should probably throw an out of memory error here, but
     
    321322
    322323    for (unsigned i = 0; i < length; ++i)
    323         array->initializeIndex(vm, i, values[i]);
     324        array->initializeIndex(scope, i, values[i]);
    324325    return array;
    325326}
     
    328329{
    329330    VM& vm = exec->vm();
    330     JSArray* array = JSArray::tryCreateForInitializationPrivate(vm, arrayStructure, length);
     331    ObjectInitializationScope scope(vm);
     332    JSArray* array = JSArray::tryCreateUninitializedRestricted(scope, arrayStructure, length);
    331333
    332334    // FIXME: we should probably throw an out of memory error here, but
     
    337339
    338340    for (int i = 0; i < static_cast<int>(length); ++i)
    339         array->initializeIndex(vm, i, values[-i]);
     341        array->initializeIndex(scope, i, values[-i]);
    340342    return array;
    341343}
  • trunk/Source/JavaScriptCore/runtime/JSCellInlines.h

    r214905 r215885  
    146146void* allocateCell(Heap& heap, size_t size)
    147147{
    148     ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
     148    ASSERT(!DisallowGC::isInEffectOnCurrentThread());
    149149    ASSERT(size >= sizeof(T));
    150150    JSCell* result = static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(size));
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r215399 r215885  
    3737#include "IndexingHeaderInlines.h"
    3838#include "JSCell.h"
     39#include "ObjectInitializationScope.h"
    3940#include "PropertySlot.h"
    4041#include "PropertyStorage.h"
     
    421422    }
    422423
    423     void initializeIndex(VM& vm, unsigned i, JSValue v)
    424     {
    425         initializeIndex(vm, i, v, indexingType());
     424    void initializeIndex(ObjectInitializationScope& scope, unsigned i, JSValue v)
     425    {
     426        initializeIndex(scope, i, v, indexingType());
    426427    }
    427428
    428429    // NOTE: Clients of this method may call it more than once for any index, and this is supposed
    429430    // to work.
    430     ALWAYS_INLINE void initializeIndex(VM& vm, unsigned i, JSValue v, IndexingType indexingType)
    431     {
     431    ALWAYS_INLINE void initializeIndex(ObjectInitializationScope& scope, unsigned i, JSValue v, IndexingType indexingType)
     432    {
     433        VM& vm = scope.vm();
    432434        Butterfly* butterfly = m_butterfly.get();
    433435        switch (indexingType) {
     
    478480    }
    479481       
    480     void initializeIndexWithoutBarrier(unsigned i, JSValue v)
    481     {
    482         initializeIndexWithoutBarrier(i, v, indexingType());
     482    void initializeIndexWithoutBarrier(ObjectInitializationScope& scope, unsigned i, JSValue v)
     483    {
     484        initializeIndexWithoutBarrier(scope, i, v, indexingType());
    483485    }
    484486
    485487    // This version of initializeIndex is for cases where you know that you will not need any
    486488    // barriers. This implies not having any data format conversions.
    487     ALWAYS_INLINE void initializeIndexWithoutBarrier(unsigned i, JSValue v, IndexingType indexingType)
     489    ALWAYS_INLINE void initializeIndexWithoutBarrier(ObjectInitializationScope&, unsigned i, JSValue v, IndexingType indexingType)
    488490    {
    489491        Butterfly* butterfly = m_butterfly.get();
  • trunk/Source/JavaScriptCore/runtime/Operations.h

    r209030 r215885  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2002, 2005-2009, 2013-2014, 2016 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2002-2017 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    262262}
    263263
     264#define SCRIBBLE_WORD static_cast<intptr_t>(0xbadbeef0)
     265
     266inline bool isScribbledValue(JSValue value)
     267{
     268    return JSValue::encode(value) == JSValue::encode(bitwise_cast<JSCell*>(SCRIBBLE_WORD));
     269}
     270
    264271inline void scribble(void* base, size_t size)
    265272{
    266273    for (size_t i = size / sizeof(EncodedJSValue); i--;) {
    267274        // Use a 16-byte aligned value to ensure that it passes the cell check.
    268         static_cast<EncodedJSValue*>(base)[i] = JSValue::encode(
    269             bitwise_cast<JSCell*>(static_cast<intptr_t>(0xbadbeef0)));
     275        static_cast<EncodedJSValue*>(base)[i] = JSValue::encode(bitwise_cast<JSCell*>(SCRIBBLE_WORD));
    270276    }
    271277}
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp

    r214313 r215885  
    11/*
    2  * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4040   
    4141    if (UNLIKELY(globalObject->isHavingABadTime())) {
    42         array = JSArray::tryCreateForInitializationPrivate(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
     42        ObjectInitializationScope scope(vm);
     43        array = JSArray::tryCreateUninitializedRestricted(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
    4344        // FIXME: we should probably throw an out of memory error here, but
    4445        // when making this change we should check that all clients of this
     
    4748        RELEASE_ASSERT(array);
    4849
    49         array->initializeIndexWithoutBarrier(0, jsEmptyString(&vm));
     50        array->initializeIndexWithoutBarrier(scope, 0, jsEmptyString(&vm));
    5051       
    5152        if (unsigned numSubpatterns = regExp->numSubpatterns()) {
    5253            for (unsigned i = 1; i <= numSubpatterns; ++i)
    53                 array->initializeIndexWithoutBarrier(i, jsUndefined());
     54                array->initializeIndexWithoutBarrier(scope, i, jsUndefined());
    5455        }
    5556    } else {
    56         array = tryCreateUninitializedRegExpMatchesArray(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
     57        ObjectInitializationScope scope(vm);
     58        array = tryCreateUninitializedRegExpMatchesArray(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
    5759        RELEASE_ASSERT(array);
    5860       
    59         array->initializeIndexWithoutBarrier(0, jsEmptyString(&vm), ArrayWithContiguous);
     61        array->initializeIndexWithoutBarrier(scope, 0, jsEmptyString(&vm), ArrayWithContiguous);
    6062       
    6163        if (unsigned numSubpatterns = regExp->numSubpatterns()) {
    6264            for (unsigned i = 1; i <= numSubpatterns; ++i)
    63                 array->initializeIndexWithoutBarrier(i, jsUndefined(), ArrayWithContiguous);
     65                array->initializeIndexWithoutBarrier(scope, i, jsUndefined(), ArrayWithContiguous);
    6466        }
    6567    }
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h

    r214313 r215885  
    3333static const PropertyOffset RegExpMatchesArrayInputPropertyOffset = 101;
    3434
    35 ALWAYS_INLINE JSArray* tryCreateUninitializedRegExpMatchesArray(VM& vm, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
     35ALWAYS_INLINE JSArray* tryCreateUninitializedRegExpMatchesArray(ObjectInitializationScope& scope, GCDeferralContext* deferralContext, Structure* structure, unsigned initialLength)
    3636{
     37    VM& vm = scope.vm();
    3738    unsigned vectorLength = initialLength;
    3839    if (vectorLength > MAX_STORAGE_VECTOR_LENGTH)
    3940        return 0;
    4041
     42    JSGlobalObject* globalObject = structure->globalObject();
     43    bool createUninitialized = globalObject->isOriginalArrayStructure(structure);
    4144    void* temp = vm.auxiliarySpace.tryAllocate(deferralContext, Butterfly::totalSize(0, structure->outOfLineCapacity(), true, vectorLength * sizeof(EncodedJSValue)));
    42     if (!temp)
     45    if (UNLIKELY(!temp))
    4346        return nullptr;
    4447    Butterfly* butterfly = Butterfly::fromBase(temp, 0, structure->outOfLineCapacity());
    4548    butterfly->setVectorLength(vectorLength);
    4649    butterfly->setPublicLength(initialLength);
    47    
    48     for (unsigned i = initialLength; i < vectorLength; ++i)
     50
     51    unsigned i = (createUninitialized ? initialLength : 0);
     52    for (; i < vectorLength; ++i)
    4953        butterfly->contiguous()[i].clear();
    50    
    51     return JSArray::createWithButterfly(vm, deferralContext, structure, butterfly);
     54
     55    JSArray* result = JSArray::createWithButterfly(vm, deferralContext, structure, butterfly);
     56    scope.notifyAllocated(result, createUninitialized);
     57    return result;
    5258}
    5359
     
    8187   
    8288    if (UNLIKELY(globalObject->isHavingABadTime())) {
    83         array = JSArray::tryCreateForInitializationPrivate(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
     89        ObjectInitializationScope scope(vm);
     90        array = JSArray::tryCreateUninitializedRestricted(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
    8491        // FIXME: we should probably throw an out of memory error here, but
    8592        // when making this change we should check that all clients of this
     
    9097        setProperties();
    9198       
    92         array->initializeIndexWithoutBarrier(0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start));
     99        array->initializeIndexWithoutBarrier(scope, 0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start));
    93100       
    94101        for (unsigned i = 1; i <= numSubpatterns; ++i) {
     
    99106            else
    100107                value = jsUndefined();
    101             array->initializeIndexWithoutBarrier(i, value);
     108            array->initializeIndexWithoutBarrier(scope, i, value);
    102109        }
    103110    } else {
    104         array = tryCreateUninitializedRegExpMatchesArray(vm, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
     111        ObjectInitializationScope scope(vm);
     112        array = tryCreateUninitializedRegExpMatchesArray(scope, &deferralContext, globalObject->regExpMatchesArrayStructure(), numSubpatterns + 1);
    105113        RELEASE_ASSERT(array);
    106114       
     
    109117        // Now the object is safe to scan by GC.
    110118
    111         array->initializeIndexWithoutBarrier(0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start), ArrayWithContiguous);
     119        array->initializeIndexWithoutBarrier(scope, 0, jsSubstringOfResolved(vm, &deferralContext, input, result.start, result.end - result.start), ArrayWithContiguous);
    112120       
    113121        for (unsigned i = 1; i <= numSubpatterns; ++i) {
     
    118126            else
    119127                value = jsUndefined();
    120             array->initializeIndexWithoutBarrier(i, value, ArrayWithContiguous);
     128            array->initializeIndexWithoutBarrier(scope, i, value, ArrayWithContiguous);
    121129        }
    122130    }
  • trunk/Source/JavaScriptCore/runtime/VMEntryScope.cpp

    r209773 r215885  
    11/*
    2  * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "VMEntryScope.h"
    2828
     29#include "DisallowVMReentry.h"
    2930#include "Options.h"
    3031#include "SamplingProfiler.h"
     
    4041    , m_globalObject(globalObject)
    4142{
     43    ASSERT(!DisallowVMReentry::isInEffectOnCurrentThread());
    4244    ASSERT(wtfThreadData().stack().isGrowingDownward());
    4345    if (!vm.entryScope) {
Note: See TracChangeset for help on using the changeset viewer.