Changeset 225891 in webkit


Ignore:
Timestamp:
Dec 13, 2017 8:10:02 PM (6 years ago)
Author:
sbarati@apple.com
Message:

Arrow functions need their own structure because they have different properties than sloppy functions
https://bugs.webkit.org/show_bug.cgi?id=180779
<rdar://problem/35814591>

Reviewed by Mark Lam.

JSTests:

  • stress/arrow-function-needs-its-own-structure.js: Added.

(assert):
(readPrototype):
(noInline.let.f1):
(noInline):

Source/JavaScriptCore:

We were using the same structure for sloppy functions and
arrow functions. This broke our IC caching machinery because
these two types of functions actually have different properties.
This patch gives them different structures.

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileNewFunction):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNewFunction):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunctionSkippingEvalEnabledCheck):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::selectStructureForNewFuncExp):
(JSC::JSFunction::create):

  • runtime/JSFunction.h:
  • runtime/JSFunctionInlines.h:

(JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):

  • runtime/JSGlobalObject.cpp:

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

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::arrowFunctionStructure const):

Location:
trunk
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r225845 r225891  
     12017-12-13  Saam Barati  <sbarati@apple.com>
     2
     3        Arrow functions need their own structure because they have different properties than sloppy functions
     4        https://bugs.webkit.org/show_bug.cgi?id=180779
     5        <rdar://problem/35814591>
     6
     7        Reviewed by Mark Lam.
     8
     9        * stress/arrow-function-needs-its-own-structure.js: Added.
     10        (assert):
     11        (readPrototype):
     12        (noInline.let.f1):
     13        (noInline):
     14
    1152017-12-13  Saam Barati  <sbarati@apple.com>
    216
  • trunk/Source/JavaScriptCore/ChangeLog

    r225887 r225891  
     12017-12-13  Saam Barati  <sbarati@apple.com>
     2
     3        Arrow functions need their own structure because they have different properties than sloppy functions
     4        https://bugs.webkit.org/show_bug.cgi?id=180779
     5        <rdar://problem/35814591>
     6
     7        Reviewed by Mark Lam.
     8
     9        We were using the same structure for sloppy functions and
     10        arrow functions. This broke our IC caching machinery because
     11        these two types of functions actually have different properties.
     12        This patch gives them different structures.
     13
     14        * dfg/DFGAbstractInterpreterInlines.h:
     15        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     16        * dfg/DFGSpeculativeJIT.cpp:
     17        (JSC::DFG::SpeculativeJIT::compileNewFunction):
     18        * ftl/FTLLowerDFGToB3.cpp:
     19        (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction):
     20        * runtime/FunctionConstructor.cpp:
     21        (JSC::constructFunctionSkippingEvalEnabledCheck):
     22        * runtime/JSFunction.cpp:
     23        (JSC::JSFunction::selectStructureForNewFuncExp):
     24        (JSC::JSFunction::create):
     25        * runtime/JSFunction.h:
     26        * runtime/JSFunctionInlines.h:
     27        (JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):
     28        * runtime/JSGlobalObject.cpp:
     29        (JSC::JSGlobalObject::init):
     30        (JSC::JSGlobalObject::visitChildren):
     31        * runtime/JSGlobalObject.h:
     32        (JSC::JSGlobalObject::arrowFunctionStructure const):
     33
    1342017-12-12  Filip Pizlo  <fpizlo@apple.com>
    235
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r225832 r225891  
    22992299        break;
    23002300
    2301     case NewFunction:
    2302         if (node->castOperand<FunctionExecutable*>()->isStrictMode()) {
    2303             forNode(node).set(
    2304                 m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->strictFunctionStructure());
    2305         } else {
    2306             forNode(node).set(
    2307                 m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->sloppyFunctionStructure());
    2308         }
    2309         break;
     2301    case NewFunction: {
     2302        JSGlobalObject* globalObject = m_codeBlock->globalObjectFor(node->origin.semantic);
     2303        Structure* structure = JSFunction::selectStructureForNewFuncExp(globalObject, node->castOperand<FunctionExecutable*>());
     2304        forNode(node).set(m_graph, structure);
     2305        break;
     2306    }
    23102307       
    23112308    case GetCallee:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r225832 r225891  
    67836783    RegisteredStructure structure = m_jit.graph().registerStructure(
    67846784        [&] () {
     6785            JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
    67856786            switch (nodeType) {
    67866787            case NewGeneratorFunction:
    6787                 return m_jit.graph().globalObjectFor(node->origin.semantic)->generatorFunctionStructure();
     6788                return globalObject->generatorFunctionStructure();
    67886789            case NewAsyncFunction:
    6789                 return m_jit.graph().globalObjectFor(node->origin.semantic)->asyncFunctionStructure();
     6790                return globalObject->asyncFunctionStructure();
    67906791            case NewAsyncGeneratorFunction:
    6791                 return m_jit.graph().globalObjectFor(node->origin.semantic)->asyncGeneratorFunctionStructure();
     6792                return globalObject->asyncGeneratorFunctionStructure();
    67926793            case NewFunction:
    6793                 if (node->castOperand<FunctionExecutable*>()->isStrictMode())
    6794                     return m_jit.graph().globalObjectFor(node->origin.semantic)->strictFunctionStructure();
    6795                 return m_jit.graph().globalObjectFor(node->origin.semantic)->sloppyFunctionStructure();
     6794                return JSFunction::selectStructureForNewFuncExp(globalObject, node->castOperand<FunctionExecutable*>());
    67966795            default:
    67976796                RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r225832 r225891  
    47374737            return;
    47384738        }
    4739        
    47404739
    47414740        RegisteredStructure structure = m_graph.registerStructure(
    47424741            [&] () {
     4742                JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
    47434743                switch (m_node->op()) {
    47444744                case NewGeneratorFunction:
    4745                     return m_graph.globalObjectFor(m_node->origin.semantic)->generatorFunctionStructure();
     4745                    return globalObject->generatorFunctionStructure();
    47464746                case NewAsyncFunction:
    4747                     return m_graph.globalObjectFor(m_node->origin.semantic)->asyncFunctionStructure();
     4747                    return globalObject->asyncFunctionStructure();
    47484748                case NewAsyncGeneratorFunction:
    4749                     return m_graph.globalObjectFor(m_node->origin.semantic)->asyncGeneratorFunctionStructure();
     4749                    return globalObject->asyncGeneratorFunctionStructure();
    47504750                case NewFunction:
    4751                     if (m_node->castOperand<FunctionExecutable*>()->isStrictMode())
    4752                         return m_graph.globalObjectFor(m_node->origin.semantic)->strictFunctionStructure();
    4753                     return m_graph.globalObjectFor(m_node->origin.semantic)->sloppyFunctionStructure();
    4754                     break;
     4751                    return JSFunction::selectStructureForNewFuncExp(globalObject, m_node->castOperand<FunctionExecutable*>());
    47554752                default:
    47564753                    RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/runtime/FunctionConstructor.cpp

    r225273 r225891  
    176176    switch (functionConstructionMode) {
    177177    case FunctionConstructionMode::Function:
    178         if (function->isStrictMode())
    179             structure = globalObject->strictFunctionStructure();
    180         else
    181             structure = globalObject->sloppyFunctionStructure();
     178        structure = JSFunction::selectStructureForNewFuncExp(globalObject, function);
    182179        break;
    183180    case FunctionConstructionMode::Generator:
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r225845 r225891  
    6666}
    6767
     68Structure* JSFunction::selectStructureForNewFuncExp(JSGlobalObject* globalObject, FunctionExecutable* executable)
     69{
     70    if (executable->isArrowFunction())
     71        return globalObject->arrowFunctionStructure();
     72    if (executable->isStrictMode())
     73        return globalObject->strictFunctionStructure();
     74    return globalObject->sloppyFunctionStructure();
     75}
     76
    6877JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope)
    6978{
    70     Structure* structure = executable->isStrictMode() ? scope->globalObject(vm)->strictFunctionStructure() : scope->globalObject(vm)->sloppyFunctionStructure();
    71     return create(vm, executable, scope, structure);
     79    return create(vm, executable, scope, selectStructureForNewFuncExp(scope->globalObject(vm), executable));
    7280}
    7381
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r224927 r225891  
    7171    }
    7272
     73    static Structure* selectStructureForNewFuncExp(JSGlobalObject*, FunctionExecutable*);
     74
    7375    JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor, const DOMJIT::Signature* = nullptr);
    7476   
  • trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h

    r225273 r225891  
    3636{
    3737    ASSERT(executable->singletonFunction()->hasBeenInvalidated());
    38     Structure* structure = executable->isStrictMode() ? scope->globalObject(vm)->strictFunctionStructure() : scope->globalObject(vm)->sloppyFunctionStructure();
    39     return createImpl(vm, executable, scope, structure);
     38    return createImpl(vm, executable, scope, selectStructureForNewFuncExp(scope->globalObject(vm), executable));
    4039}
    4140
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r225423 r225891  
    389389    m_strictFunctionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
    390390    m_sloppyFunctionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
     391    m_arrowFunctionStructure.set(vm, this, JSFunction::createStructure(vm, this, m_functionPrototype.get()));
    391392    m_customGetterSetterFunctionStructure.initLater(
    392393        [] (const Initializer<Structure>& init) {
     
    13151316    visitor.append(thisObject->m_strictFunctionStructure);
    13161317    visitor.append(thisObject->m_sloppyFunctionStructure);
     1318    visitor.append(thisObject->m_arrowFunctionStructure);
    13171319    thisObject->m_customGetterSetterFunctionStructure.visit(visitor);
    13181320    thisObject->m_boundFunctionStructure.visit(visitor);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r225273 r225891  
    323323    WriteBarrier<Structure> m_calleeStructure;
    324324    WriteBarrier<Structure> m_strictFunctionStructure;
     325    WriteBarrier<Structure> m_arrowFunctionStructure;
    325326    WriteBarrier<Structure> m_sloppyFunctionStructure;
    326327    LazyProperty<JSGlobalObject, Structure> m_boundFunctionStructure;
     
    632633    Structure* strictFunctionStructure() const { return m_strictFunctionStructure.get(); }
    633634    Structure* sloppyFunctionStructure() const { return m_sloppyFunctionStructure.get(); }
     635    Structure* arrowFunctionStructure() const { return m_arrowFunctionStructure.get(); }
    634636    Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(this); }
    635637    Structure* customGetterSetterFunctionStructure() const { return m_customGetterSetterFunctionStructure.get(this); }
Note: See TracChangeset for help on using the changeset viewer.