⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 197641 in webkit


Ignore:
Timestamp:
Mar 6, 2016, 12:11:09 PM (11 years ago)
Author:
fpizlo@apple.com
Message:

RegExpMatchesArray doesn't know how to have a bad time
​https://bugs.webkit.org/show_bug.cgi?id=155069

Reviewed by Yusuke Suzuki.

Source/JavaScriptCore:

In trunk if we are having a bad time, the regexp matches array is still allocated with a
non-slow-put indexing shape, which makes it have the wrong behavior on indexed setters on
the prototype chain.

Getting this to work right requires introducing bad time code paths into the regexp matches
array. It also requires something more drastic: making this code not play games with the
global object. The code that creates the matches array needs to have the actual global
object of the regexp native function that it's logically created by.

This is totally different from how we've handled global objects in the past because it means
that the global object is not a constant. Normally we can make it a constant because a
script executable will know its global object. But with native functions, it's the function
instance that knows the global object - not the native executable. When we inline a native
intrinsic, we are guaranteed to know the native executable but we're not guaranteed to know
the functon instance. This means that the global object may be a variable that gets computed
by looking at the instance at run-time. So, the RegExpExec/RegExpTest nodes in DFG IR now
take a global object child. That also meant adding a new node type, GetGlobalObject, which
does the thing to the callee that CallFrame::lexicalGlobalObject() would have done.
Eventually, we'll probably have to make other native intrinsics also use GetGlobalObject. It
turns out that this really isn't so bad because usually it's constant-folded anyway, since
although the intrinsic code supports executable-based inlining (which leaves the callee
instance as an unknown), it happens rarely for intrinsics. So, conveying the global object
via a child isn't any worse than conveying it via meta-data, and it's probably better than
telling the inliner not to do executable-based inlining of native intrinsics. That would
have been a confusing special-case.

This is perf-neutral on my machines but it fixes a bug and it unlocks some interesting
possibilities. For example, RegExpExec can now make a firm promise about the type of array
it's creating.

This also contains some other changes:

  • We are now using Structure::addPropertyTransition() in a lot of places even though it was meant to be an internal method with a quirky contract - for example if only works if you know that there is not existing transition. This relaxes this constraint.


  • Restores the use of "*" for heap references in JSString.h. It's very unusual to have heap references pointed at with "&", since we don't currently do that anywhere. The fact that it was using the wrong reference type also meant that the code couldn't elegantly make use of some our GC pointer helpers like jsCast<>.
  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::attemptToInlineCall):
(JSC::DFG::ByteCodeParser::handleMinMax):
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:
  • dfg/DFGOperations.h:
  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileSkipScope):
(JSC::DFG::SpeculativeJIT::compileGetGlobalObject):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::callOperation):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileSkipScope):
(JSC::FTL::DFG::LowerDFGToB3::compileGetGlobalObject):
(JSC::FTL::DFG::LowerDFGToB3::compileGetClosureVar):
(JSC::FTL::DFG::LowerDFGToB3::compileRegExpExec):
(JSC::FTL::DFG::LowerDFGToB3::compileRegExpTest):
(JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):

  • jit/JITOperations.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::haveABadTime):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObject.h:
  • runtime/JSObject.h:

(JSC::JSObject::putDirectInternal):

  • runtime/JSString.h:

(JSC::jsString):
(JSC::jsSubstring):

  • runtime/RegExpCachedResult.cpp:

(JSC::RegExpCachedResult::lastResult):

  • runtime/RegExpMatchesArray.cpp:

(JSC::tryCreateUninitializedRegExpMatchesArray):
(JSC::createRegExpMatchesArray):
(JSC::createStructureImpl):
(JSC::createRegExpMatchesArrayStructure):
(JSC::createRegExpMatchesArraySlowPutStructure):

  • runtime/RegExpMatchesArray.h:
  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::put):
(JSC::RegExpObject::exec):
(JSC::RegExpObject::match):

  • runtime/RegExpObject.h:

(JSC::RegExpObject::getLastIndex):
(JSC::RegExpObject::test):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncTest):
(JSC::regExpProtoFuncExec):
(JSC::regExpProtoFuncCompile):

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncMatch):

  • runtime/Structure.cpp:

(JSC::Structure::suggestedArrayStorageTransition):
(JSC::Structure::addPropertyTransition):
(JSC::Structure::addNewPropertyTransition):

  • runtime/Structure.h:
  • tests/stress/regexp-matches-array-bad-time.js: Added.
  • tests/stress/regexp-matches-array-slow-put.js: Added.

LayoutTests:

  • js/regress/regexp-exec-expected.txt: Added.
  • js/regress/regexp-exec.html: Added.
  • js/regress/script-tests/regexp-exec.js: Added.
Location:
trunk
Files:
5 added
33 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r197639 r197641  
     12016-03-06  Filip Pizlo  <fpizlo@apple.com>
     2
     3        RegExpMatchesArray doesn't know how to have a bad time
     4        https://bugs.webkit.org/show_bug.cgi?id=155069
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * js/regress/regexp-exec-expected.txt: Added.
     9        * js/regress/regexp-exec.html: Added.
     10        * js/regress/script-tests/regexp-exec.js: Added.
     11
    1122016-03-06  Zalan Bujtas  <zalan@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r197640 r197641  
     12016-03-06  Filip Pizlo  <fpizlo@apple.com>
     2
     3        RegExpMatchesArray doesn't know how to have a bad time
     4        https://bugs.webkit.org/show_bug.cgi?id=155069
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        In trunk if we are having a bad time, the regexp matches array is still allocated with a
     9        non-slow-put indexing shape, which makes it have the wrong behavior on indexed setters on
     10        the prototype chain.
     11
     12        Getting this to work right requires introducing bad time code paths into the regexp matches
     13        array. It also requires something more drastic: making this code not play games with the
     14        global object. The code that creates the matches array needs to have the actual global
     15        object of the regexp native function that it's logically created by.
     16
     17        This is totally different from how we've handled global objects in the past because it means
     18        that the global object is not a constant. Normally we can make it a constant because a
     19        script executable will know its global object. But with native functions, it's the function
     20        instance that knows the global object - not the native executable. When we inline a native
     21        intrinsic, we are guaranteed to know the native executable but we're not guaranteed to know
     22        the functon instance. This means that the global object may be a variable that gets computed
     23        by looking at the instance at run-time. So, the RegExpExec/RegExpTest nodes in DFG IR now
     24        take a global object child. That also meant adding a new node type, GetGlobalObject, which
     25        does the thing to the callee that CallFrame::lexicalGlobalObject() would have done.
     26        Eventually, we'll probably have to make other native intrinsics also use GetGlobalObject. It
     27        turns out that this really isn't so bad because usually it's constant-folded anyway, since
     28        although the intrinsic code supports executable-based inlining (which leaves the callee
     29        instance as an unknown), it happens rarely for intrinsics. So, conveying the global object
     30        via a child isn't any worse than conveying it via meta-data, and it's probably better than
     31        telling the inliner not to do executable-based inlining of native intrinsics. That would
     32        have been a confusing special-case.
     33
     34        This is perf-neutral on my machines but it fixes a bug and it unlocks some interesting
     35        possibilities. For example, RegExpExec can now make a firm promise about the type of array
     36        it's creating.
     37
     38        This also contains some other changes:
     39       
     40        - We are now using Structure::addPropertyTransition() in a lot of places even though it was
     41          meant to be an internal method with a quirky contract - for example if only works if you
     42          know that there is not existing transition. This relaxes this constraint.
     43       
     44        - Restores the use of "*" for heap references in JSString.h. It's very unusual to have heap
     45          references pointed at with "&", since we don't currently do that anywhere. The fact that
     46          it was using the wrong reference type also meant that the code couldn't elegantly make use
     47          of some our GC pointer helpers like jsCast<>.
     48
     49        * dfg/DFGAbstractInterpreterInlines.h:
     50        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     51        * dfg/DFGByteCodeParser.cpp:
     52        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
     53        (JSC::DFG::ByteCodeParser::handleMinMax):
     54        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
     55        * dfg/DFGClobberize.h:
     56        (JSC::DFG::clobberize):
     57        * dfg/DFGDoesGC.cpp:
     58        (JSC::DFG::doesGC):
     59        * dfg/DFGFixupPhase.cpp:
     60        (JSC::DFG::FixupPhase::fixupNode):
     61        * dfg/DFGNodeType.h:
     62        * dfg/DFGOperations.cpp:
     63        * dfg/DFGOperations.h:
     64        * dfg/DFGPredictionPropagationPhase.cpp:
     65        (JSC::DFG::PredictionPropagationPhase::propagate):
     66        * dfg/DFGSafeToExecute.h:
     67        (JSC::DFG::safeToExecute):
     68        * dfg/DFGSpeculativeJIT.cpp:
     69        (JSC::DFG::SpeculativeJIT::compileSkipScope):
     70        (JSC::DFG::SpeculativeJIT::compileGetGlobalObject):
     71        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
     72        * dfg/DFGSpeculativeJIT.h:
     73        (JSC::DFG::SpeculativeJIT::callOperation):
     74        * dfg/DFGSpeculativeJIT32_64.cpp:
     75        (JSC::DFG::SpeculativeJIT::compile):
     76        * dfg/DFGSpeculativeJIT64.cpp:
     77        (JSC::DFG::SpeculativeJIT::compile):
     78        * ftl/FTLCapabilities.cpp:
     79        (JSC::FTL::canCompile):
     80        * ftl/FTLLowerDFGToB3.cpp:
     81        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     82        (JSC::FTL::DFG::LowerDFGToB3::compileSkipScope):
     83        (JSC::FTL::DFG::LowerDFGToB3::compileGetGlobalObject):
     84        (JSC::FTL::DFG::LowerDFGToB3::compileGetClosureVar):
     85        (JSC::FTL::DFG::LowerDFGToB3::compileRegExpExec):
     86        (JSC::FTL::DFG::LowerDFGToB3::compileRegExpTest):
     87        (JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp):
     88        * jit/JITOperations.h:
     89        * runtime/JSGlobalObject.cpp:
     90        (JSC::JSGlobalObject::init):
     91        (JSC::JSGlobalObject::haveABadTime):
     92        (JSC::JSGlobalObject::visitChildren):
     93        * runtime/JSGlobalObject.h:
     94        * runtime/JSObject.h:
     95        (JSC::JSObject::putDirectInternal):
     96        * runtime/JSString.h:
     97        (JSC::jsString):
     98        (JSC::jsSubstring):
     99        * runtime/RegExpCachedResult.cpp:
     100        (JSC::RegExpCachedResult::lastResult):
     101        * runtime/RegExpMatchesArray.cpp:
     102        (JSC::tryCreateUninitializedRegExpMatchesArray):
     103        (JSC::createRegExpMatchesArray):
     104        (JSC::createStructureImpl):
     105        (JSC::createRegExpMatchesArrayStructure):
     106        (JSC::createRegExpMatchesArraySlowPutStructure):
     107        * runtime/RegExpMatchesArray.h:
     108        * runtime/RegExpObject.cpp:
     109        (JSC::RegExpObject::put):
     110        (JSC::RegExpObject::exec):
     111        (JSC::RegExpObject::match):
     112        * runtime/RegExpObject.h:
     113        (JSC::RegExpObject::getLastIndex):
     114        (JSC::RegExpObject::test):
     115        * runtime/RegExpPrototype.cpp:
     116        (JSC::regExpProtoFuncTest):
     117        (JSC::regExpProtoFuncExec):
     118        (JSC::regExpProtoFuncCompile):
     119        * runtime/StringPrototype.cpp:
     120        (JSC::stringProtoFuncMatch):
     121        * runtime/Structure.cpp:
     122        (JSC::Structure::suggestedArrayStorageTransition):
     123        (JSC::Structure::addPropertyTransition):
     124        (JSC::Structure::addNewPropertyTransition):
     125        * runtime/Structure.h:
     126        * tests/stress/regexp-matches-array-bad-time.js: Added.
     127        * tests/stress/regexp-matches-array-slow-put.js: Added.
     128
    11292016-03-06  Yusuke Suzuki  <utatane.tea@gmail.com>
    2130
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r197622 r197641  
    15551555           
    15561556    case RegExpExec:
    1557         if (node->child1().useKind() == RegExpObjectUse
    1558             && node->child2().useKind() == StringUse) {
     1557        if (node->child2().useKind() == RegExpObjectUse
     1558            && node->child3().useKind() == StringUse) {
    15591559            // This doesn't clobber the world since there are no conversions to perform.
    15601560        } else
    15611561            clobberWorld(node->origin.semantic, clobberLimit);
    1562         forNode(node).makeHeapTop();
     1562        if (JSValue globalObjectValue = forNode(node->child1()).m_value) {
     1563            if (JSGlobalObject* globalObject = jsDynamicCast<JSGlobalObject*>(globalObjectValue)) {
     1564                if (!globalObject->isHavingABadTime()) {
     1565                    m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
     1566                    Structure* structure = globalObject->regExpMatchesArrayStructure();
     1567                    m_graph.registerStructure(structure);
     1568                    forNode(node).set(m_graph, structure);
     1569                    forNode(node).merge(SpecOther);
     1570                    break;
     1571                }
     1572            }
     1573        }
     1574        forNode(node).setType(m_graph, SpecOther | SpecArray);
    15631575        break;
    15641576
    15651577    case RegExpTest:
    1566         if (node->child1().useKind() == RegExpObjectUse
    1567             && node->child2().useKind() == StringUse) {
     1578        if (node->child2().useKind() == RegExpObjectUse
     1579            && node->child3().useKind() == StringUse) {
    15681580            // This doesn't clobber the world since there are no conversions to perform.
    15691581        } else
    … …  
    18791891            break;
    18801892        }
     1893        forNode(node).setType(m_graph, SpecObjectOther);
     1894        break;
     1895    }
     1896
     1897    case GetGlobalObject: {
     1898        JSValue child = forNode(node->child1()).value();
     1899        if (child) {
     1900            setConstant(node, *m_graph.freeze(JSValue(asObject(child)->globalObject())));
     1901            break;
     1902        }
     1903
     1904        if (forNode(node->child1()).m_structure.isFinite()) {
     1905            JSGlobalObject* globalObject = nullptr;
     1906            bool ok = true;
     1907            forNode(node->child1()).m_structure.forEach(
     1908                [&] (Structure* structure) {
     1909                    if (!globalObject)
     1910                        globalObject = structure->globalObject();
     1911                    else if (globalObject != structure->globalObject())
     1912                        ok = false;
     1913                });
     1914            if (globalObject && ok) {
     1915                setConstant(node, *m_graph.freeze(JSValue(globalObject)));
     1916                break;
     1917            }
     1918        }
     1919
    18811920        forNode(node).setType(m_graph, SpecObjectOther);
    18821921        break;
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r197520 r197641  
    203203    // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
    204204    template<typename ChecksFunctor>
    205     bool handleIntrinsicCall(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
     205    bool handleIntrinsicCall(Node* callee, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
    206206    template<typename ChecksFunctor>
    207207    bool handleIntrinsicGetter(int resultOperand, const GetByIdVariant& intrinsicVariant, Node* thisNode, const ChecksFunctor& insertChecks);
    … …  
    16021602        Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
    16031603        if (intrinsic != NoIntrinsic) {
    1604             if (handleIntrinsicCall(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
     1604            if (handleIntrinsicCall(callTargetNode, resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
    16051605                RELEASE_ASSERT(didInsertChecks);
    16061606                addToGraph(Phantom, callTargetNode);
    … …  
    19921992
    19931993template<typename ChecksFunctor>
    1994 bool ByteCodeParser::handleIntrinsicCall(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
     1994bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
    19951995{
    19961996    switch (intrinsic) {
    … …  
    21732173       
    21742174        insertChecks();
    2175         Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
     2175        Node* regExpExec = addToGraph(RegExpExec, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
    21762176        set(VirtualRegister(resultOperand), regExpExec);
    21772177       
    … …  
    21842184       
    21852185        insertChecks();
    2186         Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
     2186        Node* regExpExec = addToGraph(RegExpTest, OpInfo(0), OpInfo(prediction), addToGraph(GetGlobalObject, callee), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)));
    21872187        set(VirtualRegister(resultOperand), regExpExec);
    21882188       
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r197622 r197641  
    135135    case GetScope:
    136136    case SkipScope:
     137    case GetGlobalObject:
    137138    case StringCharCodeAt:
    138139    case CompareStrictEq:
    … …  
    10791080    case RegExpExec:
    10801081    case RegExpTest:
    1081         if (node->child1().useKind() == RegExpObjectUse
    1082             && node->child2().useKind() == StringUse) {
     1082        if (node->child2().useKind() == RegExpObjectUse
     1083            && node->child3().useKind() == StringUse) {
    10831084            read(RegExpState);
    10841085            write(RegExpState);
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r197549 r197641  
    112112    case GetScope:
    113113    case SkipScope:
     114    case GetGlobalObject:
    114115    case GetClosureVar:
    115116    case PutClosureVar:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r197622 r197641  
    880880        case RegExpExec:
    881881        case RegExpTest: {
    882             if (node->child1()->shouldSpeculateRegExpObject()) {
    883                 fixEdge<RegExpObjectUse>(node->child1());
    884 
    885                 if (node->child2()->shouldSpeculateString())
    886                     fixEdge<StringUse>(node->child2());
     882            fixEdge<KnownCellUse>(node->child1());
     883           
     884            if (node->child2()->shouldSpeculateRegExpObject()) {
     885                fixEdge<RegExpObjectUse>(node->child2());
     886
     887                if (node->child3()->shouldSpeculateString())
     888                    fixEdge<StringUse>(node->child3());
    887889            }
    888890            break;
    … …  
    10501052        case GetScope:
    10511053        case GetGetter:
    1052         case GetSetter: {
     1054        case GetSetter:
     1055        case GetGlobalObject: {
    10531056            fixEdge<KnownCellUse>(node->child1());
    10541057            break;
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r197549 r197641  
    213213    macro(GetScope, NodeResultJS) \
    214214    macro(SkipScope, NodeResultJS) \
     215    macro(GetGlobalObject, NodeResultJS) \
    215216    macro(GetClosureVar, NodeResultJS) \
    216217    macro(PutClosureVar, NodeMustGenerate) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r197622 r197641  
    620620}
    621621       
    622 EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, RegExpObject* regExpObject, JSString* argument)
    623 {
    624     VM& vm = exec->vm();
    625     NativeCallFrameTracer tracer(&vm, exec);
    626    
    627     return JSValue::encode(regExpObject->exec(exec, argument));
     622EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* argument)
     623{
     624    VM& vm = globalObject->vm();
     625    NativeCallFrameTracer tracer(&vm, exec);
     626   
     627    return JSValue::encode(regExpObject->exec(exec, globalObject, argument));
    628628}
    629629       
    630 EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
    631 {
    632     VM& vm = exec->vm();
     630EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
     631{
     632    VM& vm = globalObject->vm();
    633633    NativeCallFrameTracer tracer(&vm, exec);
    634634   
    … …  
    638638    if (!input)
    639639        return JSValue::encode(jsUndefined());
    640     return JSValue::encode(regExpObject->exec(exec, input));
     640    return JSValue::encode(regExpObject->exec(exec, globalObject, input));
    641641}
    642642       
    643 EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
    644 {
    645     VM& vm = exec->vm();
     643EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
     644{
     645    VM& vm = globalObject->vm();
    646646    NativeCallFrameTracer tracer(&vm, exec);
    647647
    … …  
    655655    if (!input)
    656656        return JSValue::encode(jsUndefined());
    657     return JSValue::encode(asRegExpObject(base)->exec(exec, input));
     657    return JSValue::encode(asRegExpObject(base)->exec(exec, globalObject, input));
    658658}
    659659       
    660 size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, RegExpObject* regExpObject, JSString* input)
    661 {
    662     VM& vm = exec->vm();
    663     NativeCallFrameTracer tracer(&vm, exec);
    664 
    665     return regExpObject->test(exec, input);
    666 }
    667 
    668 size_t JIT_OPERATION operationRegExpTest(ExecState* exec, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
    669 {
    670     VM& vm = exec->vm();
     660size_t JIT_OPERATION operationRegExpTestString(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, JSString* input)
     661{
     662    VM& vm = globalObject->vm();
     663    NativeCallFrameTracer tracer(&vm, exec);
     664
     665    return regExpObject->test(exec, globalObject, input);
     666}
     667
     668size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSGlobalObject* globalObject, RegExpObject* regExpObject, EncodedJSValue encodedArgument)
     669{
     670    VM& vm = globalObject->vm();
    671671    NativeCallFrameTracer tracer(&vm, exec);
    672672
    … …  
    676676    if (!input)
    677677        return false;
    678     return regExpObject->test(exec, input);
    679 }
    680 
    681 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
    682 {
    683     VM& vm = exec->vm();
     678    return regExpObject->test(exec, globalObject, input);
     679}
     680
     681size_t JIT_OPERATION operationRegExpTestGeneric(ExecState* exec, JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedArgument)
     682{
     683    VM& vm = globalObject->vm();
    684684    NativeCallFrameTracer tracer(&vm, exec);
    685685
    … …  
    695695    if (!input)
    696696        return false;
    697     return asRegExpObject(base)->test(exec, input);
     697    return asRegExpObject(base)->test(exec, globalObject, input);
    698698}
    699699
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r197622 r197641  
    102102EncodedJSValue JIT_OPERATION operationArrayPop(ExecState*, JSArray*) WTF_INTERNAL;
    103103EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState*, JSArray*) WTF_INTERNAL;
    104 EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState*, RegExpObject*, JSString*) WTF_INTERNAL;
    105 EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
    106 EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
     104EncodedJSValue JIT_OPERATION operationRegExpExecString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;
     105EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
     106EncodedJSValue JIT_OPERATION operationRegExpExecGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
    107107// These comparisons return a boolean within a size_t such that the value is zero extended to fill the register.
    108 size_t JIT_OPERATION operationRegExpTestString(ExecState*, RegExpObject*, JSString*) WTF_INTERNAL;
    109 size_t JIT_OPERATION operationRegExpTest(ExecState*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
    110 size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
     108size_t JIT_OPERATION operationRegExpTestString(ExecState*, JSGlobalObject*, RegExpObject*, JSString*) WTF_INTERNAL;
     109size_t JIT_OPERATION operationRegExpTest(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue) WTF_INTERNAL;
     110size_t JIT_OPERATION operationRegExpTestGeneric(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
    111111size_t JIT_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
    112112size_t JIT_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r197549 r197641  
    551551        }
    552552           
    553         case SkipScope: {
     553        case SkipScope:
     554        case GetGlobalObject: {
    554555            changed |= setPrediction(SpecObjectOther);
    555556            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r197549 r197641  
    208208    case GetScope:
    209209    case SkipScope:
     210    case GetGlobalObject:
    210211    case GetClosureVar:
    211212    case PutClosureVar:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r197549 r197641  
    53435343}
    53445344
     5345void SpeculativeJIT::compileGetGlobalObject(Node* node)
     5346{
     5347    SpeculateCellOperand object(this, node->child1());
     5348    GPRTemporary result(this);
     5349    GPRTemporary scratch(this);
     5350    m_jit.emitLoadStructure(object.gpr(), result.gpr(), scratch.gpr());
     5351    m_jit.loadPtr(JITCompiler::Address(result.gpr(), Structure::globalObjectOffset()), result.gpr());
     5352    cellResult(result.gpr(), node);
     5353}
     5354
    53455355void SpeculativeJIT::compileGetArrayLength(Node* node)
    53465356{
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r197622 r197641  
    12181218    }
    12191219
    1220     JITCompiler::Call callOperation(J_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    1221     {
    1222         m_jit.setupArgumentsWithExecState(arg1, arg2);
    1223         return appendCallSetResult(operation, result);
    1224     }
    1225 
    1226     JITCompiler::Call callOperation(J_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    1227     {
    1228         m_jit.setupArgumentsWithExecState(arg1, arg2);
     1220    JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1221    {
     1222        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1223        return appendCallSetResult(operation, result);
     1224    }
     1225
     1226    JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1227    {
     1228        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
    12291229        return appendCallSetResult(operation, result);
    12301230    }
    … …  
    14471447        return appendCallSetResult(operation, result);
    14481448    }
    1449     JITCompiler::Call callOperation(S_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1449    JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1450    {
     1451        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1452        return appendCallSetResult(operation, result);
     1453    }
     1454    JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1455    {
     1456        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1457        return appendCallSetResult(operation, result);
     1458    }
     1459    JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1460    {
     1461        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
     1462        return appendCallSetResult(operation, result);
     1463    }
     1464
     1465    JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    14501466    {
    14511467        m_jit.setupArgumentsWithExecState(arg1, arg2);
    14521468        return appendCallSetResult(operation, result);
    14531469    }
    1454     JITCompiler::Call callOperation(S_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
     1470    JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    14551471    {
    14561472        m_jit.setupArgumentsWithExecState(arg1, arg2);
    14571473        return appendCallSetResult(operation, result);
    14581474    }
    1459 
    1460     JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    1461     {
    1462         m_jit.setupArgumentsWithExecState(arg1, arg2);
    1463         return appendCallSetResult(operation, result);
    1464     }
    1465     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    1466     {
    1467         m_jit.setupArgumentsWithExecState(arg1, arg2);
     1475    JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1476    {
     1477        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
    14681478        return appendCallSetResult(operation, result);
    14691479    }
    … …  
    17231733        return appendCallSetResult(operation, result);
    17241734    }
    1725     JITCompiler::Call callOperation(J_JITOperation_EReoJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
    1726     {
    1727         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
    1728         return appendCallSetResult(operation, resultPayload, resultTag);
    1729     }
    1730     JITCompiler::Call callOperation(J_JITOperation_EReoJss operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
    1731     {
    1732         m_jit.setupArgumentsWithExecState(arg1, arg2);
     1735    JITCompiler::Call callOperation(J_JITOperation_EGReoJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
     1736    {
     1737        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3Payload, arg3Tag);
     1738        return appendCallSetResult(operation, resultPayload, resultTag);
     1739    }
     1740    JITCompiler::Call callOperation(J_JITOperation_EGReoJss operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1741    {
     1742        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
    17331743        return appendCallSetResult(operation, resultPayload, resultTag);
    17341744    }
    … …  
    18301840        return appendCallSetResult(operation, result);
    18311841    }
    1832     JITCompiler::Call callOperation(S_JITOperation_EReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
    1833     {
    1834         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
    1835         return appendCallSetResult(operation, result);
    1836     }
    1837     JITCompiler::Call callOperation(S_JITOperation_EReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
    1838     {
    1839         m_jit.setupArgumentsWithExecState(arg1, arg2);
     1842    JITCompiler::Call callOperation(S_JITOperation_EGJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
     1843    {
     1844        m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
     1845        return appendCallSetResult(operation, result);
     1846    }
     1847    JITCompiler::Call callOperation(S_JITOperation_EGReoJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
     1848    {
     1849        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3Payload, arg3Tag);
     1850        return appendCallSetResult(operation, result);
     1851    }
     1852    JITCompiler::Call callOperation(S_JITOperation_EGReoJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     1853    {
     1854        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
    18401855        return appendCallSetResult(operation, result);
    18411856    }
    … …  
    18431858    {
    18441859        m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
     1860        return appendCallSetResult(operation, resultPayload, resultTag);
     1861    }
     1862    JITCompiler::Call callOperation(J_JITOperation_EGJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
     1863    {
     1864        m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
    18451865        return appendCallSetResult(operation, resultPayload, resultTag);
    18461866    }
    … …  
    23102330    void compileGetScope(Node*);
    23112331    void compileSkipScope(Node*);
     2332    void compileGetGlobalObject(Node*);
    23122333
    23132334    void compileGetArrayLength(Node*);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r197622 r197641  
    28372837
    28382838    case RegExpExec: {
    2839         if (node->child1().useKind() == RegExpObjectUse) {
    2840             if (node->child2().useKind() == StringUse) {
    2841                 SpeculateCellOperand base(this, node->child1());
    2842                 SpeculateCellOperand argument(this, node->child2());
     2839        SpeculateCellOperand globalObject(this, node->child1());
     2840        GPRReg globalObjectGPR = globalObject.gpr();
     2841       
     2842        if (node->child2().useKind() == RegExpObjectUse) {
     2843            if (node->child3().useKind() == StringUse) {
     2844                SpeculateCellOperand base(this, node->child2());
     2845                SpeculateCellOperand argument(this, node->child3());
    28432846                GPRReg baseGPR = base.gpr();
    28442847                GPRReg argumentGPR = argument.gpr();
    2845                 speculateRegExpObject(node->child1(), baseGPR);
    2846                 speculateString(node->child2(), argumentGPR);
     2848                speculateRegExpObject(node->child2(), baseGPR);
     2849                speculateString(node->child3(), argumentGPR);
    28472850               
    28482851                flushRegisters();
    … …  
    28502853                GPRFlushedCallResult resultPayload(this);
    28512854                callOperation(
    2852                     operationRegExpExecString, resultTag.gpr(), resultPayload.gpr(), baseGPR,
    2853                     argumentGPR);
     2855                    operationRegExpExecString, resultTag.gpr(), resultPayload.gpr(),
     2856                    globalObjectGPR, baseGPR, argumentGPR);
    28542857                m_jit.exceptionCheck();
    28552858               
    … …  
    28582861            }
    28592862           
    2860             SpeculateCellOperand base(this, node->child1());
    2861             JSValueOperand argument(this, node->child2());
     2863            SpeculateCellOperand base(this, node->child2());
     2864            JSValueOperand argument(this, node->child3());
    28622865            GPRReg baseGPR = base.gpr();
    28632866            GPRReg argumentTagGPR = argument.tagGPR();
    28642867            GPRReg argumentPayloadGPR = argument.payloadGPR();
    2865             speculateRegExpObject(node->child1(), baseGPR);
     2868            speculateRegExpObject(node->child2(), baseGPR);
    28662869       
    28672870            flushRegisters();
    … …  
    28692872            GPRFlushedCallResult resultPayload(this);
    28702873            callOperation(
    2871                 operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), baseGPR, argumentTagGPR,
    2872                 argumentPayloadGPR);
     2874                operationRegExpExec, resultTag.gpr(), resultPayload.gpr(), globalObjectGPR, baseGPR,
     2875                argumentTagGPR, argumentPayloadGPR);
    28732876            m_jit.exceptionCheck();
    28742877       
    … …  
    28772880        }
    28782881       
    2879         JSValueOperand base(this, node->child1());
    2880         JSValueOperand argument(this, node->child2());
     2882        JSValueOperand base(this, node->child2());
     2883        JSValueOperand argument(this, node->child3());
    28812884        GPRReg baseTagGPR = base.tagGPR();
    28822885        GPRReg basePayloadGPR = base.payloadGPR();
    … …  
    28872890        GPRFlushedCallResult2 resultTag(this);
    28882891        GPRFlushedCallResult resultPayload(this);
    2889         callOperation(operationRegExpExecGeneric, resultTag.gpr(), resultPayload.gpr(), baseTagGPR, basePayloadGPR, argumentTagGPR, argumentPayloadGPR);
     2892        callOperation(
     2893            operationRegExpExecGeneric, resultTag.gpr(), resultPayload.gpr(), globalObjectGPR,
     2894            baseTagGPR, basePayloadGPR, argumentTagGPR, argumentPayloadGPR);
    28902895        m_jit.exceptionCheck();
    28912896       
    … …  
    28952900       
    28962901    case RegExpTest: {
    2897         if (node->child1().useKind() == RegExpObjectUse) {
    2898             if (node->child2().useKind() == StringUse) {
    2899                 SpeculateCellOperand base(this, node->child1());
    2900                 SpeculateCellOperand argument(this, node->child2());
     2902        SpeculateCellOperand globalObject(this, node->child1());
     2903        GPRReg globalObjectGPR = globalObject.gpr();
     2904       
     2905        if (node->child2().useKind() == RegExpObjectUse) {
     2906            if (node->child3().useKind() == StringUse) {
     2907                SpeculateCellOperand base(this, node->child2());
     2908                SpeculateCellOperand argument(this, node->child3());
    29012909                GPRReg baseGPR = base.gpr();
    29022910                GPRReg argumentGPR = argument.gpr();
    2903                 speculateRegExpObject(node->child1(), baseGPR);
    2904                 speculateString(node->child2(), argumentGPR);
     2911                speculateRegExpObject(node->child2(), baseGPR);
     2912                speculateString(node->child3(), argumentGPR);
    29052913               
    29062914                flushRegisters();
    29072915                GPRFlushedCallResult result(this);
    2908                 callOperation(operationRegExpTestString, result.gpr(), baseGPR, argumentGPR);
     2916                callOperation(
     2917                    operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
    29092918                m_jit.exceptionCheck();
    29102919               
    … …  
    29132922            }
    29142923           
    2915             SpeculateCellOperand base(this, node->child1());
    2916             JSValueOperand argument(this, node->child2());
     2924            SpeculateCellOperand base(this, node->child2());
     2925            JSValueOperand argument(this, node->child3());
    29172926            GPRReg baseGPR = base.gpr();
    29182927            GPRReg argumentTagGPR = argument.tagGPR();
    29192928            GPRReg argumentPayloadGPR = argument.payloadGPR();
    2920             speculateRegExpObject(node->child1(), baseGPR);
     2929            speculateRegExpObject(node->child2(), baseGPR);
    29212930       
    29222931            flushRegisters();
    29232932            GPRFlushedCallResult result(this);
    29242933            callOperation(
    2925                 operationRegExpTest, result.gpr(), baseGPR, argumentTagGPR, argumentPayloadGPR);
     2934                operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentTagGPR,
     2935                argumentPayloadGPR);
    29262936            m_jit.exceptionCheck();
    29272937       
    … …  
    29302940        }
    29312941       
    2932         JSValueOperand base(this, node->child1());
    2933         JSValueOperand argument(this, node->child2());
     2942        JSValueOperand base(this, node->child2());
     2943        JSValueOperand argument(this, node->child3());
    29342944        GPRReg baseTagGPR = base.tagGPR();
    29352945        GPRReg basePayloadGPR = base.payloadGPR();
    … …  
    29392949        flushRegisters();
    29402950        GPRFlushedCallResult result(this);
    2941         callOperation(operationRegExpTestGeneric, result.gpr(), baseTagGPR, basePayloadGPR, argumentTagGPR, argumentPayloadGPR);
     2951        callOperation(
     2952            operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseTagGPR, basePayloadGPR,
     2953            argumentTagGPR, argumentPayloadGPR);
    29422954        m_jit.exceptionCheck();
    29432955       
    … …  
    39023914        break;
    39033915       
     3916    case GetGlobalObject:
     3917        compileGetGlobalObject(node);
     3918        break;
     3919       
    39043920    case GetClosureVar: {
    39053921        SpeculateCellOperand base(this, node->child1());
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r197622 r197641  
    29632963
    29642964    case RegExpExec: {
    2965         if (node->child1().useKind() == RegExpObjectUse) {
    2966             if (node->child2().useKind() == StringUse) {
    2967                 SpeculateCellOperand base(this, node->child1());
    2968                 SpeculateCellOperand argument(this, node->child2());
     2965        SpeculateCellOperand globalObject(this, node->child1());
     2966        GPRReg globalObjectGPR = globalObject.gpr();
     2967       
     2968        if (node->child2().useKind() == RegExpObjectUse) {
     2969            if (node->child3().useKind() == StringUse) {
     2970                SpeculateCellOperand base(this, node->child2());
     2971                SpeculateCellOperand argument(this, node->child3());
    29692972                GPRReg baseGPR = base.gpr();
    29702973                GPRReg argumentGPR = argument.gpr();
    2971                 speculateRegExpObject(node->child1(), baseGPR);
    2972                 speculateString(node->child2(), argumentGPR);
     2974                speculateRegExpObject(node->child2(), baseGPR);
     2975                speculateString(node->child3(), argumentGPR);
    29732976               
    29742977                flushRegisters();
    29752978                GPRFlushedCallResult result(this);
    2976                 callOperation(operationRegExpExecString, result.gpr(), baseGPR, argumentGPR);
     2979                callOperation(operationRegExpExecString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
    29772980                m_jit.exceptionCheck();
    29782981               
    … …  
    29812984            }
    29822985           
    2983             SpeculateCellOperand base(this, node->child1());
    2984             JSValueOperand argument(this, node->child2());
     2986            SpeculateCellOperand base(this, node->child2());
     2987            JSValueOperand argument(this, node->child3());
    29852988            GPRReg baseGPR = base.gpr();
    29862989            GPRReg argumentGPR = argument.gpr();
    2987             speculateRegExpObject(node->child1(), baseGPR);
     2990            speculateRegExpObject(node->child2(), baseGPR);
    29882991       
    29892992            flushRegisters();
    29902993            GPRFlushedCallResult result(this);
    2991             callOperation(operationRegExpExec, result.gpr(), baseGPR, argumentGPR);
     2994            callOperation(operationRegExpExec, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
    29922995            m_jit.exceptionCheck();
    29932996       
    … …  
    29962999        }
    29973000       
    2998         JSValueOperand base(this, node->child1());
    2999         JSValueOperand argument(this, node->child2());
     3001        JSValueOperand base(this, node->child2());
     3002        JSValueOperand argument(this, node->child3());
    30003003        GPRReg baseGPR = base.gpr();
    30013004        GPRReg argumentGPR = argument.gpr();
    … …  
    30033006        flushRegisters();
    30043007        GPRFlushedCallResult result(this);
    3005         callOperation(operationRegExpExecGeneric, result.gpr(), baseGPR, argumentGPR);
     3008        callOperation(operationRegExpExecGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
    30063009        m_jit.exceptionCheck();
    30073010       
    … …  
    30113014
    30123015    case RegExpTest: {
    3013         if (node->child1().useKind() == RegExpObjectUse) {
    3014             if (node->child2().useKind() == StringUse) {
    3015                 SpeculateCellOperand base(this, node->child1());
    3016                 SpeculateCellOperand argument(this, node->child2());
     3016        SpeculateCellOperand globalObject(this, node->child1());
     3017        GPRReg globalObjectGPR = globalObject.gpr();
     3018       
     3019        if (node->child2().useKind() == RegExpObjectUse) {
     3020            if (node->child3().useKind() == StringUse) {
     3021                SpeculateCellOperand base(this, node->child2());
     3022                SpeculateCellOperand argument(this, node->child3());
    30173023                GPRReg baseGPR = base.gpr();
    30183024                GPRReg argumentGPR = argument.gpr();
    3019                 speculateRegExpObject(node->child1(), baseGPR);
    3020                 speculateString(node->child2(), argumentGPR);
     3025                speculateRegExpObject(node->child2(), baseGPR);
     3026                speculateString(node->child3(), argumentGPR);
    30213027               
    30223028                flushRegisters();
    30233029                GPRFlushedCallResult result(this);
    3024                 callOperation(operationRegExpTestString, result.gpr(), baseGPR, argumentGPR);
     3030                callOperation(operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
    30253031                m_jit.exceptionCheck();
    30263032               
    … …  
    30303036            }
    30313037           
    3032             SpeculateCellOperand base(this, node->child1());
    3033             JSValueOperand argument(this, node->child2());
     3038            SpeculateCellOperand base(this, node->child2());
     3039            JSValueOperand argument(this, node->child3());
    30343040            GPRReg baseGPR = base.gpr();
    30353041            GPRReg argumentGPR = argument.gpr();
    3036             speculateRegExpObject(node->child1(), baseGPR);
     3042            speculateRegExpObject(node->child2(), baseGPR);
    30373043       
    30383044            flushRegisters();
    30393045            GPRFlushedCallResult result(this);
    3040             callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
     3046            callOperation(operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
    30413047            m_jit.exceptionCheck();
    30423048       
    … …  
    30463052        }
    30473053       
    3048         JSValueOperand base(this, node->child1());
    3049         JSValueOperand argument(this, node->child2());
     3054        JSValueOperand base(this, node->child2());
     3055        JSValueOperand argument(this, node->child3());
    30503056        GPRReg baseGPR = base.gpr();
    30513057        GPRReg argumentGPR = argument.gpr();
    … …  
    30533059        flushRegisters();
    30543060        GPRFlushedCallResult result(this);
    3055         callOperation(operationRegExpTestGeneric, result.gpr(), baseGPR, argumentGPR);
     3061        callOperation(operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
    30563062        m_jit.exceptionCheck();
    30573063       
    … …  
    39313937        compileSkipScope(node);
    39323938        break;
     3939
     3940    case GetGlobalObject:
     3941        compileGetGlobalObject(node);
     3942        break;
    39333943       
    39343944    case GetClosureVar: {
  • trunk/Source/JavaScriptCore/dfg/DFGStructureRegistrationPhase.cpp

    r194835 r197641  
    150150                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->generatorFunctionStructure());
    151151                    break;
    152                    
     152
    153153                default:
    154154                    break;
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r197549 r197641  
    112112    case LoopHint:
    113113    case SkipScope:
     114    case GetGlobalObject:
    114115    case CreateActivation:
    115116    case NewArrowFunction:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r197622 r197641  
    748748        case SkipScope:
    749749            compileSkipScope();
     750            break;
     751        case GetGlobalObject:
     752            compileGetGlobalObject();
    750753            break;
    751754        case GetClosureVar:
    … …  
    44764479        setJSValue(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSScope_next));
    44774480    }
     4481
     4482    void compileGetGlobalObject()
     4483    {
     4484        LValue structure = loadStructure(lowCell(m_node->child1()));
     4485        setJSValue(m_out.loadPtr(structure, m_heaps.Structure_globalObject));
     4486    }
    44784487   
    44794488    void compileGetClosureVar()
    … …  
    64416450    void compileRegExpExec()
    64426451    {
    6443         if (m_node->child1().useKind() == RegExpObjectUse) {
    6444             LValue base = lowRegExpObject(m_node->child1());
    6445            
    6446             if (m_node->child2().useKind() == StringUse) {
    6447                 LValue argument = lowString(m_node->child2());
     6452        LValue globalObject = lowCell(m_node->child1());
     6453       
     6454        if (m_node->child2().useKind() == RegExpObjectUse) {
     6455            LValue base = lowRegExpObject(m_node->child2());
     6456           
     6457            if (m_node->child3().useKind() == StringUse) {
     6458                LValue argument = lowString(m_node->child3());
    64486459                LValue result = vmCall(
    6449                     Int64, m_out.operation(operationRegExpExecString), m_callFrame, base, argument);
     6460                    Int64, m_out.operation(operationRegExpExecString), m_callFrame, globalObject,
     6461                    base, argument);
    64506462                setJSValue(result);
    64516463                return;
    64526464            }
    64536465           
    6454             LValue argument = lowJSValue(m_node->child2());
    6455             setJSValue(
    6456                 vmCall(Int64, m_out.operation(operationRegExpExec), m_callFrame, base, argument));
    6457             return;
    6458         }
    6459        
    6460         LValue base = lowJSValue(m_node->child1());
    6461         LValue argument = lowJSValue(m_node->child2());
    6462         setJSValue(
    6463             vmCall(Int64, m_out.operation(operationRegExpExecGeneric), m_callFrame, base, argument));
     6466            LValue argument = lowJSValue(m_node->child3());
     6467            LValue result = vmCall(
     6468                Int64, m_out.operation(operationRegExpExec), m_callFrame, globalObject, base,
     6469                argument);
     6470            setJSValue(result);
     6471            return;
     6472        }
     6473       
     6474        LValue base = lowJSValue(m_node->child2());
     6475        LValue argument = lowJSValue(m_node->child3());
     6476        LValue result = vmCall(
     6477            Int64, m_out.operation(operationRegExpExecGeneric), m_callFrame, globalObject, base,
     6478            argument);
     6479        setJSValue(result);
    64646480    }
    64656481
    64666482    void compileRegExpTest()
    64676483    {
    6468         if (m_node->child1().useKind() == RegExpObjectUse) {
    6469             LValue base = lowRegExpObject(m_node->child1());
    6470            
    6471             if (m_node->child2().useKind() == StringUse) {
    6472                 LValue argument = lowString(m_node->child2());
     6484        LValue globalObject = lowCell(m_node->child1());
     6485       
     6486        if (m_node->child2().useKind() == RegExpObjectUse) {
     6487            LValue base = lowRegExpObject(m_node->child2());
     6488           
     6489            if (m_node->child3().useKind() == StringUse) {
     6490                LValue argument = lowString(m_node->child3());
    64736491                LValue result = vmCall(
    6474                     Int32, m_out.operation(operationRegExpTestString), m_callFrame, base, argument);
     6492                    Int32, m_out.operation(operationRegExpTestString), m_callFrame, globalObject,
     6493                    base, argument);
    64756494                setBoolean(result);
    64766495                return;
    64776496            }
    64786497
    6479             LValue argument = lowJSValue(m_node->child2());
    6480             setBoolean(
    6481                 vmCall(Int32, m_out.operation(operationRegExpTest), m_callFrame, base, argument));
    6482             return;
    6483         }
    6484 
    6485         LValue base = lowJSValue(m_node->child1());
    6486         LValue argument = lowJSValue(m_node->child2());
    6487         setBoolean(
    6488             vmCall(Int32, m_out.operation(operationRegExpTestGeneric), m_callFrame, base, argument));
     6498            LValue argument = lowJSValue(m_node->child3());
     6499            LValue result = vmCall(
     6500                Int32, m_out.operation(operationRegExpTest), m_callFrame, globalObject, base,
     6501                argument);
     6502            setBoolean(result);
     6503            return;
     6504        }
     6505
     6506        LValue base = lowJSValue(m_node->child2());
     6507        LValue argument = lowJSValue(m_node->child3());
     6508        LValue result = vmCall(
     6509            Int32, m_out.operation(operationRegExpTestGeneric), m_callFrame, globalObject, base,
     6510            argument);
     6511        setBoolean(result);
    64896512    }
    64906513
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r197622 r197641  
    123123typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EDA)(ExecState*, double, JSArray*);
    124124typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EE)(ExecState*, ExecState*);
     125typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EGReoJ)(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue);
     126typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EGReoJss)(ExecState*, JSGlobalObject*, RegExpObject*, JSString*);
     127typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EGJJ)(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue);
    125128typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EI)(ExecState*, UniquedStringImpl*);
    126129typedef EncodedJSValue JIT_OPERATION (*J_JITOperation_EJ)(ExecState*, EncodedJSValue);
    … …  
    202205typedef size_t JIT_OPERATION (*S_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
    203206typedef size_t JIT_OPERATION (*S_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
     207typedef size_t JIT_OPERATION (*S_JITOperation_EGJJ)(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue);
     208typedef size_t JIT_OPERATION (*S_JITOperation_EGReoJ)(ExecState*, JSGlobalObject*, RegExpObject*, EncodedJSValue);
     209typedef size_t JIT_OPERATION (*S_JITOperation_EGReoJss)(ExecState*, JSGlobalObject*, RegExpObject*, JSString*);
    204210typedef size_t JIT_OPERATION (*S_JITOperation_EJ)(ExecState*, EncodedJSValue);
    205211typedef size_t JIT_OPERATION (*S_JITOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r197536 r197641  
    11/*
    2  * Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007, 2008, 2009, 2014-2016 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    44 *
    … …  
    365365    m_regExpPrototype.set(vm, this, RegExpPrototype::create(vm, this, RegExpPrototype::createStructure(vm, this, m_objectPrototype.get()), emptyRegex));
    366366    m_regExpStructure.set(vm, this, RegExpObject::createStructure(vm, this, m_regExpPrototype.get()));
    367     m_regExpMatchesArrayStructure.set(vm, this, createRegExpMatchesArrayStructure(vm, *this));
     367    m_regExpMatchesArrayStructure.set(vm, this, createRegExpMatchesArrayStructure(vm, this));
     368    m_regExpMatchesArraySlowPutStructure.set(vm, this, createRegExpMatchesArraySlowPutStructure(vm, this));
    368369
    369370    m_moduleRecordStructure.set(vm, this, JSModuleRecord::createStructure(vm, this, m_objectPrototype.get()));
    … …  
    762763    for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
    763764        m_arrayStructureForIndexingShapeDuringAllocation[i].set(vm, this, originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
     765
     766    // Same for any special array structures.
     767    m_regExpMatchesArrayStructure.set(vm, this, m_regExpMatchesArraySlowPutStructure.get());
    764768   
    765769    // Make sure that all objects that have indexed storage switch to the slow kind of
    … …  
    901905    visitor.append(&thisObject->m_iteratorResultObjectStructure);
    902906    visitor.append(&thisObject->m_regExpMatchesArrayStructure);
     907    visitor.append(&thisObject->m_regExpMatchesArraySlowPutStructure);
    903908    visitor.append(&thisObject->m_moduleRecordStructure);
    904909    visitor.append(&thisObject->m_moduleNamespaceObjectStructure);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r197261 r197641  
    11/*
    22 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
    3  *  Copyright (C) 2007, 2008, 2009, 2014, 2015 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2007, 2008, 2009, 2014-2016 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
    … …  
    279279    WriteBarrier<Structure> m_iteratorResultObjectStructure;
    280280    WriteBarrier<Structure> m_regExpMatchesArrayStructure;
     281    WriteBarrier<Structure> m_regExpMatchesArraySlowPutStructure;
    281282    WriteBarrier<Structure> m_moduleRecordStructure;
    282283    WriteBarrier<Structure> m_moduleNamespaceObjectStructure;
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r197614 r197641  
    13771377    DeferredStructureTransitionWatchpointFire deferredWatchpointFire;
    13781378   
    1379     newStructure = Structure::addPropertyTransition(
     1379    newStructure = Structure::addNewPropertyTransition(
    13801380        vm, structure, propertyName, attributes, offset, slot.context(), &deferredWatchpointFire);
    13811381    newStructure->willStoreValueForNewTransition(
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r197485 r197641  
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2014, 2016 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
    … …  
    294294    }
    295295
    296     void finishCreation(ExecState& exec, JSString& base, unsigned offset, unsigned length)
    297     {
    298         VM& vm = exec.vm();
     296    void finishCreation(VM& vm, ExecState* exec, JSString* base, unsigned offset, unsigned length)
     297    {
    299298        Base::finishCreation(vm);
    300299        ASSERT(!sumOverflows<int32_t>(offset, length));
    301         ASSERT(offset + length <= base.length());
     300        ASSERT(offset + length <= base->length());
    302301        m_length = length;
    303         setIs8Bit(base.is8Bit());
     302        setIs8Bit(base->is8Bit());
    304303        setIsSubstring(true);
    305         if (base.isSubstring()) {
    306             JSRopeString& baseRope = static_cast<JSRopeString&>(base);
    307             substringBase().set(vm, this, baseRope.substringBase().get());
    308             substringOffset() = baseRope.substringOffset() + offset;
     304        if (base->isSubstring()) {
     305            JSRopeString* baseRope = jsCast<JSRopeString*>(base);
     306            substringBase().set(vm, this, baseRope->substringBase().get());
     307            substringOffset() = baseRope->substringOffset() + offset;
    309308        } else {
    310             substringBase().set(vm, this, &base);
     309            substringBase().set(vm, this, base);
    311310            substringOffset() = offset;
    312311
    … …  
    314313            // Resolve non-substring rope bases so we don't have to deal with it.
    315314            // FIXME: Evaluate if this would be worth adding more branches.
    316             if (base.isRope())
    317                 static_cast<JSRopeString&>(base).resolveRope(&exec);
     315            if (base->isRope())
     316                jsCast<JSRopeString*>(base)->resolveRope(exec);
    318317        }
    319318    }
    … …  
    357356    }
    358357
    359     static JSString* create(ExecState& exec, JSString& base, unsigned offset, unsigned length)
    360     {
    361         JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(exec.vm().heap)) JSRopeString(exec.vm());
    362         newString->finishCreation(exec, base, offset, length);
     358    static JSString* create(VM& vm, ExecState* exec, JSString* base, unsigned offset, unsigned length)
     359    {
     360        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
     361        newString->finishCreation(vm, exec, base, offset, length);
    363362        return newString;
    364363    }
    … …  
    543542}
    544543
    545 inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
     544inline JSString* jsSubstring(VM& vm, ExecState* exec, JSString* s, unsigned offset, unsigned length)
    546545{
    547546    ASSERT(offset <= static_cast<unsigned>(s->length()));
    548547    ASSERT(length <= static_cast<unsigned>(s->length()));
    549548    ASSERT(offset + length <= static_cast<unsigned>(s->length()));
    550     VM& vm = exec->vm();
    551549    if (!length)
    552550        return vm.smallStrings.emptyString();
    553551    if (!offset && length == s->length())
    554552        return s;
    555     return JSRopeString::create(*exec, *s, offset, length);
     553    return JSRopeString::create(vm, exec, s, offset, length);
     554}
     555
     556inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
     557{
     558    return jsSubstring(exec->vm(), exec, s, offset, length);
    556559}
    557560
  • trunk/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp

    r175372 r197641  
    11/*
    2  * Copyright (C) 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
    … …  
    4646    if (!m_reified) {
    4747        m_reifiedInput.set(exec->vm(), owner, m_lastInput.get());
    48         m_reifiedResult.set(exec->vm(), owner, createRegExpMatchesArray(exec, m_lastInput.get(), m_lastRegExp.get(), m_result));
     48        m_reifiedResult.set(exec->vm(), owner, createRegExpMatchesArray(exec, exec->lexicalGlobalObject(), m_lastInput.get(), m_lastRegExp.get(), m_result));
    4949        m_reified = true;
    5050    }
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp

    r185597 r197641  
    11/*
    2  * Copyright (C) 2012-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
    … …  
    5151}
    5252
    53 JSArray* createRegExpMatchesArray(ExecState* exec, JSString* input, RegExp* regExp, MatchResult result)
     53JSArray* createRegExpMatchesArray(
     54    ExecState* exec, JSGlobalObject* globalObject, JSString* input, RegExp* regExp,
     55    MatchResult result)
    5456{
     57    SamplingRegion samplingRegion("createRegExpMatchesArray");
     58   
    5559    ASSERT(result);
    56     VM& vm = exec->vm();
    57     JSArray* array = tryCreateUninitializedRegExpMatchesArray(vm, exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
    58     RELEASE_ASSERT(array);
     60    VM& vm = globalObject->vm();
    5961
    60     SamplingRegion samplingRegion("Reifying substring properties");
    61 
    62     array->initializeIndex(vm, 0, jsSubstring(exec, input, result.start, result.end - result.start), ArrayWithContiguous);
    63 
    64     if (unsigned numSubpatterns = regExp->numSubpatterns()) {
    65         Vector<int, 32> subpatternResults;
    66         int position = regExp->match(vm, input->value(exec), result.start, subpatternResults);
    67         ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == result.start);
    68         ASSERT(result.start == static_cast<size_t>(subpatternResults[0]));
    69         ASSERT(result.end == static_cast<size_t>(subpatternResults[1]));
    70 
    71         for (unsigned i = 1; i <= numSubpatterns; ++i) {
    72             int start = subpatternResults[2 * i];
    73             if (start >= 0)
    74                 array->initializeIndex(vm, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start), ArrayWithContiguous);
    75             else
    76                 array->initializeIndex(vm, i, jsUndefined(), ArrayWithContiguous);
     62    JSArray* array;
     63    if (UNLIKELY(globalObject->isHavingABadTime())) {
     64        array = JSArray::tryCreateUninitialized(vm, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
     65       
     66        array->initializeIndex(vm, 0, jsSubstring(vm, exec, input, result.start, result.end - result.start));
     67       
     68        if (unsigned numSubpatterns = regExp->numSubpatterns()) {
     69            Vector<int, 32> subpatternResults;
     70            int position = regExp->match(vm, input->value(exec), result.start, subpatternResults);
     71            ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == result.start);
     72            ASSERT(result.start == static_cast<size_t>(subpatternResults[0]));
     73            ASSERT(result.end == static_cast<size_t>(subpatternResults[1]));
     74           
     75            for (unsigned i = 1; i <= numSubpatterns; ++i) {
     76                int start = subpatternResults[2 * i];
     77                if (start >= 0)
     78                    array->initializeIndex(vm, i, jsSubstring(vm, exec, input, start, subpatternResults[2 * i + 1] - start));
     79                else
     80                    array->initializeIndex(vm, i, jsUndefined());
     81            }
     82        }
     83    } else {
     84        array = tryCreateUninitializedRegExpMatchesArray(vm, globalObject->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
     85        RELEASE_ASSERT(array);
     86       
     87        array->initializeIndex(vm, 0, jsSubstring(vm, exec, input, result.start, result.end - result.start), ArrayWithContiguous);
     88       
     89        if (unsigned numSubpatterns = regExp->numSubpatterns()) {
     90            Vector<int, 32> subpatternResults;
     91            int position = regExp->match(vm, input->value(exec), result.start, subpatternResults);
     92            ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == result.start);
     93            ASSERT(result.start == static_cast<size_t>(subpatternResults[0]));
     94            ASSERT(result.end == static_cast<size_t>(subpatternResults[1]));
     95           
     96            for (unsigned i = 1; i <= numSubpatterns; ++i) {
     97                int start = subpatternResults[2 * i];
     98                if (start >= 0)
     99                    array->initializeIndex(vm, i, jsSubstring(vm, exec, input, start, subpatternResults[2 * i + 1] - start), ArrayWithContiguous);
     100                else
     101                    array->initializeIndex(vm, i, jsUndefined(), ArrayWithContiguous);
     102            }
    77103        }
    78104    }
    … …  
    84110}
    85111
    86 Structure* createRegExpMatchesArrayStructure(VM& vm, JSGlobalObject& globalObject)
     112static Structure* createStructureImpl(VM& vm, JSGlobalObject* globalObject, IndexingType indexingType)
    87113{
    88     Structure* structure = globalObject.arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous);
     114    Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType);
    89115    PropertyOffset offset;
    90     structure = structure->addPropertyTransition(vm, structure, vm.propertyNames->index, 0, offset);
     116    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->index, 0, offset);
    91117    ASSERT(offset == indexPropertyOffset);
    92     structure = structure->addPropertyTransition(vm, structure, vm.propertyNames->input, 0, offset);
     118    structure = Structure::addPropertyTransition(vm, structure, vm.propertyNames->input, 0, offset);
    93119    ASSERT(offset == inputPropertyOffset);
    94120    return structure;
    95121}
    96122
     123Structure* createRegExpMatchesArrayStructure(VM& vm, JSGlobalObject* globalObject)
     124{
     125    return createStructureImpl(vm, globalObject, ArrayWithContiguous);
     126}
     127
     128Structure* createRegExpMatchesArraySlowPutStructure(VM& vm, JSGlobalObject* globalObject)
     129{
     130    return createStructureImpl(vm, globalObject, ArrayWithSlowPutArrayStorage);
     131}
     132
    97133} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h

    r185597 r197641  
    11/*
    2  *  Copyright (C) 2008 Apple Inc. All Rights Reserved.
     2 *  Copyright (C) 2008, 2016 Apple Inc. All Rights Reserved.
    33 *
    44 *  This library is free software; you can redistribute it and/or
    … …  
    2727namespace JSC {
    2828
    29 JSArray* createRegExpMatchesArray(ExecState*, JSString*, RegExp*, MatchResult);
    30 Structure* createRegExpMatchesArrayStructure(VM&, JSGlobalObject&);
     29JSArray* createRegExpMatchesArray(ExecState*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
     30Structure* createRegExpMatchesArrayStructure(VM&, JSGlobalObject*);
     31Structure* createRegExpMatchesArraySlowPutStructure(VM&, JSGlobalObject*);
    3132
    3233}
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp

    r197640 r197641  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007, 2008, 2012 Apple Inc. All Rights Reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2012, 2016 Apple Inc. All Rights Reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
    … …  
    160160}
    161161
    162 JSValue RegExpObject::exec(ExecState* exec, JSString* string)
    163 {
    164     if (MatchResult result = match(exec, string))
    165         return createRegExpMatchesArray(exec, string, regExp(), result);
     162JSValue RegExpObject::exec(ExecState* exec, JSGlobalObject* globalObject, JSString* string)
     163{
     164    if (MatchResult result = match(exec, globalObject, string))
     165        return createRegExpMatchesArray(exec, globalObject, string, regExp(), result);
    166166    return jsNull();
    167167}
    168168
    169169// Shared implementation used by test and exec.
    170 MatchResult RegExpObject::match(ExecState* exec, JSString* string)
     170MatchResult RegExpObject::match(ExecState* exec, JSGlobalObject* globalObject, JSString* string)
    171171{
    172172    RegExp* regExp = this->regExp();
    173     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     173    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
    174174    String input = string->value(exec);
    175     VM& vm = exec->vm();
     175    VM& vm = globalObject->vm();
    176176    if (!regExp->global())
    177177        return regExpConstructor->performMatch(vm, regExp, string, input, 0);
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.h

    r197640 r197641  
    6767    }
    6868
    69     bool test(ExecState* exec, JSString* string) { return match(exec, string); }
    70     JSValue exec(ExecState*, JSString*);
     69    bool test(ExecState* exec, JSGlobalObject* globalObject, JSString* string) { return match(exec, globalObject, string); }
     70    JSValue exec(ExecState*, JSGlobalObject*, JSString*);
    7171
    7272    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    … …  
    103103
    104104private:
    105     MatchResult match(ExecState*, JSString*);
     105    MatchResult match(ExecState*, JSGlobalObject*, JSString*);
    106106
    107107    WriteBarrier<RegExp> m_regExp;
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp

    r197485 r197641  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
     3 *  Copyright (C) 2003, 2007, 2008, 2016 Apple Inc. All Rights Reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
    … …  
    103103    if (!string)
    104104        return JSValue::encode(jsUndefined());
    105     return JSValue::encode(jsBoolean(asRegExpObject(thisValue)->test(exec, string)));
     105    return JSValue::encode(jsBoolean(asRegExpObject(thisValue)->test(exec, exec->lexicalGlobalObject(), string)));
    106106}
    107107
    … …  
    114114    if (!string)
    115115        return JSValue::encode(jsUndefined());
    116     return JSValue::encode(asRegExpObject(thisValue)->exec(exec, string));
     116    return JSValue::encode(asRegExpObject(thisValue)->exec(exec, exec->lexicalGlobalObject(), string));
    117117}
    118118
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r197614 r197641  
    10361036    JSString* string = thisValue.toString(exec);
    10371037    String s = string->value(exec);
    1038     VM* vm = &exec->vm();
     1038    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     1039    VM* vm = &globalObject->vm();
    10391040
    10401041    JSValue a0 = exec->argument(0);
    … …  
    10681069            return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage()));
    10691070    }
    1070     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     1071    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
    10711072    MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, s, 0);
    10721073    // case without 'g' flag is handled like RegExp.prototype.exec
    10731074    if (!global)
    1074         return JSValue::encode(result ? createRegExpMatchesArray(exec, string, regExp, result) : jsNull());
     1075        return JSValue::encode(result ? createRegExpMatchesArray(exec, globalObject, string, regExp, result) : jsNull());
    10751076
    10761077    // return array of matches
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r197539 r197641  
    11/*
    2  * Copyright (C) 2008, 2009, 2013-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2013-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
    … …  
    444444}
    445445
    446 Structure* Structure::addPropertyTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset& offset, PutPropertySlot::Context context, DeferredStructureTransitionWatchpointFire* deferred)
     446Structure* Structure::addPropertyTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset& offset)
     447{
     448    Structure* newStructure = addPropertyTransitionToExistingStructure(
     449        structure, propertyName, attributes, offset);
     450    if (newStructure)
     451        return newStructure;
     452
     453    return addNewPropertyTransition(
     454        vm, structure, propertyName, attributes, offset, PutPropertySlot::UnknownContext);
     455}
     456
     457Structure* Structure::addNewPropertyTransition(VM& vm, Structure* structure, PropertyName propertyName, unsigned attributes, PropertyOffset& offset, PutPropertySlot::Context context, DeferredStructureTransitionWatchpointFire* deferred)
    447458{
    448459    ASSERT(!structure->isDictionary());
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r197563 r197641  
    169169    static void dumpStatistics();
    170170
    171     JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&, Structure*, PropertyName, unsigned attributes, PropertyOffset&, PutPropertySlot::Context = PutPropertySlot::UnknownContext, DeferredStructureTransitionWatchpointFire* = nullptr);
     171    JS_EXPORT_PRIVATE static Structure* addPropertyTransition(VM&, Structure*, PropertyName, unsigned attributes, PropertyOffset&);
     172    JS_EXPORT_PRIVATE static Structure* addNewPropertyTransition(VM&, Structure*, PropertyName, unsigned attributes, PropertyOffset&, PutPropertySlot::Context = PutPropertySlot::UnknownContext, DeferredStructureTransitionWatchpointFire* = nullptr);
    172173    static Structure* addPropertyTransitionToExistingStructureConcurrently(Structure*, UniquedStringImpl* uid, unsigned attributes, PropertyOffset&);
    173174    JS_EXPORT_PRIVATE static Structure* addPropertyTransitionToExistingStructure(Structure*, PropertyName, unsigned attributes, PropertyOffset&);
    … …  
    246247       
    247248    JSGlobalObject* globalObject() const { return m_globalObject.get(); }
     249
     250    // NOTE: This method should only be called during the creation of structures, since the global
     251    // object of a structure is presumed to be immutable in a bunch of places.
    248252    void setGlobalObject(VM& vm, JSGlobalObject* globalObject) { m_globalObject.set(vm, this, globalObject); }
    249253       
Note: See TracChangeset for help on using the changeset viewer.