Changeset 223523 in webkit


Ignore:
Timestamp:
Oct 17, 2017 5:02:01 AM (6 years ago)
Author:
Yusuke Suzuki
Message:

[JSC] proto getter should be fast
https://bugs.webkit.org/show_bug.cgi?id=178067

Reviewed by Saam Barati.

JSTests:

  • stress/dfg-object-proto-accessor.js: Added.

(shouldBe):
(shouldThrow):
(target):

  • stress/dfg-object-proto-getter.js: Added.

(shouldBe):
(shouldThrow):
(target):

  • stress/dfg-object-prototype-of.js: Added.

(shouldBe):
(shouldThrow):
(target):

  • stress/dfg-reflect-get-prototype-of.js: Added.

(shouldBe):
(shouldThrow):
(target):

  • stress/object-get-prototype-of-filtered.js: Added.

(shouldBe):
(shouldThrow):
(target):
(i.Cocoa):

  • stress/object-get-prototype-of-mono-proto.js: Added.

(shouldBe):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(target):

  • stress/object-get-prototype-of-poly-mono-proto.js: Added.

(shouldBe):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(target):

  • stress/object-get-prototype-of-poly-proto.js: Added.

(shouldBe):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(target):

  • stress/object-proto-getter-filtered.js: Added.

(shouldBe):
(shouldThrow):
(target):
(i.Cocoa):

  • stress/object-proto-getter-poly-mono-proto.js: Added.

(shouldBe):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(target):

  • stress/object-proto-getter-poly-proto.js: Added.

(shouldBe):
(makePolyProtoObject.foo.C):
(makePolyProtoObject.foo):
(makePolyProtoObject):
(target):

  • stress/object-prototype-proto-accessors-should-throw-on-undefined-this.js:
  • stress/string-proto.js: Added.

(shouldBe):
(target):

Source/JavaScriptCore:

In our ES6 class implementation, we access proto field to retrieve super constructor.
Currently, it is handled as an usual getter call to a generic function. And DFG just emits
Call node for this. It is inefficient since typically we know the prototype of the given
object when accessing object.__proto__ since we emit CheckStructure for this object.
If Structure has mono proto, we can immediately fold it to constant value. If it is poly proto,
we can still change this to efficient access to poly proto slot.

This patch implements GetPrototypeOf DFG node. This node efficiently accesses to prototype of
the given object. And in AI and ByteCodeParser phase, we attempt to fold it to constant.
ByteCodeParser's folding is a bit important since we have callee.__proto__ code to get super
constructor. If we can change this to constant, we can reify CallLinkInfo with this constant.
This paves the way to optimizing ArrayConstructor super calls[1], which is particularly important
for ARES-6 ML.

And we also optimize Reflect.getPrototypeOf and Object.getPrototypeOf with this GetPrototypeOf node.

Currently, proto access for poly proto object is not handled well in IC. But we add code handling
poly proto in GetPrototypeOf since Reflect.getPrototypeOf and Object.getPrototypeOf can use it.
Once IC starts handling poly proto & intrinsic getter well, this code will be used for that too.

This patch improves SixSpeed super.es6 by 3.42x.

baseline patched

super.es6 123.6666+-3.9917 36.1684+-1.0351 definitely 3.4192x faster

[1]: https://bugs.webkit.org/show_bug.cgi?id=178064

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
(JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
(JSC::DFG::ByteCodeParser::handleGetById):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGHeapLocation.cpp:

(WTF::printInternal):

  • dfg/DFGHeapLocation.h:
  • dfg/DFGNode.h:

(JSC::DFG::Node::hasHeapPrediction):
(JSC::DFG::Node::shouldSpeculateFunction):

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

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::speculateFunction):
(JSC::DFG::SpeculativeJIT::speculateFinalObject):
(JSC::DFG::SpeculativeJIT::compileGetPrototypeOf):

  • dfg/DFGSpeculativeJIT.h:
  • 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::compileGetPrototypeOf):
(JSC::FTL::DFG::LowerDFGToB3::compileInstanceOf):

  • jit/IntrinsicEmitter.cpp:

(JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
(JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):

  • runtime/Intrinsic.cpp:

(JSC::intrinsicName):

  • runtime/Intrinsic.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncProtoGetter):

  • runtime/JSGlobalObjectFunctions.h:
  • runtime/ObjectConstructor.cpp:
  • runtime/ReflectObject.cpp:

LayoutTests:

  • js/object-literal-shorthand-construction-expected.txt:
  • js/script-tests/object-literal-shorthand-construction.js:

(set 2):
(get 1):

  • js/script-tests/sloppy-getter-setter-global-object.js:
  • js/sloppy-getter-setter-global-object-expected.txt:
Location:
trunk
Files:
13 added
36 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r223318 r223523  
     12017-10-10  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] __proto__ getter should be fast
     4        https://bugs.webkit.org/show_bug.cgi?id=178067
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/dfg-object-proto-accessor.js: Added.
     9        (shouldBe):
     10        (shouldThrow):
     11        (target):
     12        * stress/dfg-object-proto-getter.js: Added.
     13        (shouldBe):
     14        (shouldThrow):
     15        (target):
     16        * stress/dfg-object-prototype-of.js: Added.
     17        (shouldBe):
     18        (shouldThrow):
     19        (target):
     20        * stress/dfg-reflect-get-prototype-of.js: Added.
     21        (shouldBe):
     22        (shouldThrow):
     23        (target):
     24        * stress/object-get-prototype-of-filtered.js: Added.
     25        (shouldBe):
     26        (shouldThrow):
     27        (target):
     28        (i.Cocoa):
     29        * stress/object-get-prototype-of-mono-proto.js: Added.
     30        (shouldBe):
     31        (makePolyProtoObject.foo.C):
     32        (makePolyProtoObject.foo):
     33        (makePolyProtoObject):
     34        (target):
     35        * stress/object-get-prototype-of-poly-mono-proto.js: Added.
     36        (shouldBe):
     37        (makePolyProtoObject.foo.C):
     38        (makePolyProtoObject.foo):
     39        (makePolyProtoObject):
     40        (target):
     41        * stress/object-get-prototype-of-poly-proto.js: Added.
     42        (shouldBe):
     43        (makePolyProtoObject.foo.C):
     44        (makePolyProtoObject.foo):
     45        (makePolyProtoObject):
     46        (target):
     47        * stress/object-proto-getter-filtered.js: Added.
     48        (shouldBe):
     49        (shouldThrow):
     50        (target):
     51        (i.Cocoa):
     52        * stress/object-proto-getter-poly-mono-proto.js: Added.
     53        (shouldBe):
     54        (makePolyProtoObject.foo.C):
     55        (makePolyProtoObject.foo):
     56        (makePolyProtoObject):
     57        (target):
     58        * stress/object-proto-getter-poly-proto.js: Added.
     59        (shouldBe):
     60        (makePolyProtoObject.foo.C):
     61        (makePolyProtoObject.foo):
     62        (makePolyProtoObject):
     63        (target):
     64        * stress/object-prototype-proto-accessors-should-throw-on-undefined-this.js:
     65        * stress/string-proto.js: Added.
     66        (shouldBe):
     67        (target):
     68
    1692017-10-14  Yusuke Suzuki  <utatane.tea@gmail.com>
    270
  • trunk/JSTests/stress/object-prototype-proto-accessors-should-throw-on-undefined-this.js

    r207518 r223523  
    3535}
    3636
    37 runTest(10000, testInvokeGetter, undefined, "TypeError: Object.prototype.__proto__ called on null or undefined");
     37runTest(10000, testInvokeGetter, undefined, "TypeError: undefined is not an object (evaluating 'getter()')");
    3838runTest(10100, testInvokeSetter, undefined, "TypeError: Object.prototype.__proto__ called on null or undefined");
  • trunk/LayoutTests/ChangeLog

    r223514 r223523  
     12017-10-10  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] __proto__ getter should be fast
     4        https://bugs.webkit.org/show_bug.cgi?id=178067
     5
     6        Reviewed by Saam Barati.
     7
     8        * js/object-literal-shorthand-construction-expected.txt:
     9        * js/script-tests/object-literal-shorthand-construction.js:
     10        (set 2):
     11        (get 1):
     12        * js/script-tests/sloppy-getter-setter-global-object.js:
     13        * js/sloppy-getter-setter-global-object-expected.txt:
     14
    1152017-10-17  Antti Koivisto  <antti@apple.com>
    216
  • trunk/LayoutTests/js/object-literal-shorthand-construction-expected.txt

    r215682 r223523  
    6565PASS ({__proto__: this.__proto__}) instanceof Array is false
    6666PASS __proto__ = [] threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
    67 PASS ({__proto__: __proto__}) instanceof Array threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
     67PASS ({__proto__: __proto__}) instanceof Array threw exception TypeError: undefined is not an object (evaluating '__proto__').
    6868SyntaxErrors
    6969PASS ({break}) threw exception SyntaxError: Cannot use the keyword 'break' as a shorthand property name..
  • trunk/LayoutTests/js/script-tests/object-literal-shorthand-construction.js

    r215682 r223523  
    114114shouldBeFalse("({__proto__: this.__proto__}) instanceof Array");
    115115shouldThrow("__proto__ = []", '"TypeError: Object.prototype.__proto__ called on null or undefined"');
    116 shouldThrow("({__proto__: __proto__}) instanceof Array", '"TypeError: Object.prototype.__proto__ called on null or undefined"');
     116shouldThrow("({__proto__: __proto__}) instanceof Array", '"TypeError: undefined is not an object (evaluating \'__proto__\')"');
    117117
    118118// Keywords - Syntax Errors
  • trunk/LayoutTests/js/script-tests/sloppy-getter-setter-global-object.js

    r207518 r223523  
    2626shouldNotThrow("Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').set(['foo'])");
    2727
    28 shouldThrow("(0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get)()", "\"TypeError: Object.prototype.__proto__ called on null or undefined\"");
     28shouldThrow("(0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get)()", "\"TypeError: undefined is not an object (evaluating '(0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get)()')\"");
    2929shouldThrow("(0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').set)(['foo'])", "\"TypeError: Object.prototype.__proto__ called on null or undefined\"");
    3030
    3131
    3232var top_level_sloppy_getter = Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get;
    33 shouldThrow("top_level_sloppy_getter();", "\"TypeError: Object.prototype.__proto__ called on null or undefined\"");
     33shouldThrow("top_level_sloppy_getter();", "\"TypeError: undefined is not an object (evaluating 'top_level_sloppy_getter()')\"");
    3434
    3535var top_level_sloppy_setter = Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').set;
  • trunk/LayoutTests/js/sloppy-getter-setter-global-object-expected.txt

    r207518 r223523  
    99PASS Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get() did not throw exception.
    1010PASS Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').set(['foo']) did not throw exception.
    11 PASS (0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get)() threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
     11PASS (0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get)() threw exception TypeError: undefined is not an object (evaluating '(0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').get)()').
    1212PASS (0,Object.getOwnPropertyDescriptor(Object.prototype,'__proto__').set)(['foo']) threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
    13 PASS top_level_sloppy_getter(); threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
     13PASS top_level_sloppy_getter(); threw exception TypeError: undefined is not an object (evaluating 'top_level_sloppy_getter()').
    1414PASS top_level_sloppy_setter(['foo']); threw exception TypeError: Object.prototype.__proto__ called on null or undefined.
    1515PASS successfullyParsed is true
  • trunk/Source/JavaScriptCore/ChangeLog

    r223476 r223523  
     12017-10-10  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] __proto__ getter should be fast
     4        https://bugs.webkit.org/show_bug.cgi?id=178067
     5
     6        Reviewed by Saam Barati.
     7
     8        In our ES6 class implementation, we access __proto__ field to retrieve super constructor.
     9        Currently, it is handled as an usual getter call to a generic function. And DFG just emits
     10        Call node for this. It is inefficient since typically we know the `prototype` of the given
     11        object when accessing `object.__proto__` since we emit CheckStructure for this `object`.
     12        If Structure has mono proto, we can immediately fold it to constant value. If it is poly proto,
     13        we can still change this to efficient access to poly proto slot.
     14
     15        This patch implements GetPrototypeOf DFG node. This node efficiently accesses to prototype of
     16        the given object. And in AI and ByteCodeParser phase, we attempt to fold it to constant.
     17        ByteCodeParser's folding is a bit important since we have `callee.__proto__` code to get super
     18        constructor. If we can change this to constant, we can reify CallLinkInfo with this constant.
     19        This paves the way to optimizing ArrayConstructor super calls[1], which is particularly important
     20        for ARES-6 ML.
     21
     22        And we also optimize Reflect.getPrototypeOf and Object.getPrototypeOf with this GetPrototypeOf node.
     23
     24        Currently, __proto__ access for poly proto object is not handled well in IC. But we add code handling
     25        poly proto in GetPrototypeOf since Reflect.getPrototypeOf and Object.getPrototypeOf can use it.
     26        Once IC starts handling poly proto & intrinsic getter well, this code will be used for that too.
     27
     28        This patch improves SixSpeed super.es6 by 3.42x.
     29
     30                                 baseline                  patched
     31
     32        super.es6           123.6666+-3.9917     ^     36.1684+-1.0351        ^ definitely 3.4192x faster
     33
     34        [1]: https://bugs.webkit.org/show_bug.cgi?id=178064
     35
     36        * dfg/DFGAbstractInterpreterInlines.h:
     37        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     38        * dfg/DFGByteCodeParser.cpp:
     39        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
     40        (JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
     41        (JSC::DFG::ByteCodeParser::handleGetById):
     42        * dfg/DFGClobberize.h:
     43        (JSC::DFG::clobberize):
     44        * dfg/DFGDoesGC.cpp:
     45        (JSC::DFG::doesGC):
     46        * dfg/DFGFixupPhase.cpp:
     47        (JSC::DFG::FixupPhase::fixupNode):
     48        (JSC::DFG::FixupPhase::fixupGetPrototypeOf):
     49        * dfg/DFGHeapLocation.cpp:
     50        (WTF::printInternal):
     51        * dfg/DFGHeapLocation.h:
     52        * dfg/DFGNode.h:
     53        (JSC::DFG::Node::hasHeapPrediction):
     54        (JSC::DFG::Node::shouldSpeculateFunction):
     55        * dfg/DFGNodeType.h:
     56        * dfg/DFGOperations.cpp:
     57        * dfg/DFGOperations.h:
     58        * dfg/DFGPredictionPropagationPhase.cpp:
     59        * dfg/DFGSafeToExecute.h:
     60        (JSC::DFG::safeToExecute):
     61        * dfg/DFGSpeculativeJIT.cpp:
     62        (JSC::DFG::SpeculativeJIT::speculateFunction):
     63        (JSC::DFG::SpeculativeJIT::speculateFinalObject):
     64        (JSC::DFG::SpeculativeJIT::compileGetPrototypeOf):
     65        * dfg/DFGSpeculativeJIT.h:
     66        * dfg/DFGSpeculativeJIT32_64.cpp:
     67        (JSC::DFG::SpeculativeJIT::compile):
     68        * dfg/DFGSpeculativeJIT64.cpp:
     69        (JSC::DFG::SpeculativeJIT::compile):
     70        * ftl/FTLCapabilities.cpp:
     71        (JSC::FTL::canCompile):
     72        * ftl/FTLLowerDFGToB3.cpp:
     73        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     74        (JSC::FTL::DFG::LowerDFGToB3::compileGetPrototypeOf):
     75        (JSC::FTL::DFG::LowerDFGToB3::compileInstanceOf):
     76        * jit/IntrinsicEmitter.cpp:
     77        (JSC::IntrinsicGetterAccessCase::canEmitIntrinsicGetter):
     78        (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
     79        * runtime/Intrinsic.cpp:
     80        (JSC::intrinsicName):
     81        * runtime/Intrinsic.h:
     82        * runtime/JSGlobalObject.cpp:
     83        (JSC::JSGlobalObject::init):
     84        * runtime/JSGlobalObjectFunctions.cpp:
     85        (JSC::globalFuncProtoGetter):
     86        * runtime/JSGlobalObjectFunctions.h:
     87        * runtime/ObjectConstructor.cpp:
     88        * runtime/ReflectObject.cpp:
     89
    1902017-10-17  Keith Miller  <keith_miller@apple.com>
    291
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r223318 r223523  
    27412741        break;
    27422742    }
     2743
     2744    case GetPrototypeOf: {
     2745        AbstractValue& value = forNode(node->child1());
     2746        if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
     2747            bool canFold = !value.m_structure.isClear();
     2748            JSValue prototype;
     2749            value.m_structure.forEach([&] (RegisteredStructure structure) {
     2750                auto getPrototypeMethod = structure->classInfo()->methodTable.getPrototype;
     2751                MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
     2752                if (getPrototypeMethod != defaultGetPrototype) {
     2753                    canFold = false;
     2754                    return;
     2755                }
     2756
     2757                if (structure->hasPolyProto()) {
     2758                    canFold = false;
     2759                    return;
     2760                }
     2761                if (!prototype)
     2762                    prototype = structure->storedPrototype();
     2763                else if (prototype != structure->storedPrototype())
     2764                    canFold = false;
     2765            });
     2766
     2767            if (prototype && canFold) {
     2768                setConstant(node, *m_graph.freeze(prototype));
     2769                break;
     2770            }
     2771        }
     2772
     2773        switch (node->child1().useKind()) {
     2774        case ArrayUse:
     2775        case FunctionUse:
     2776        case FinalObjectUse:
     2777            break;
     2778        default:
     2779            clobberWorld(node->origin.semantic, clobberLimit);
     2780            break;
     2781        }
     2782        forNode(node).setType(m_graph, SpecObject | SpecOther);
     2783        break;
     2784    }
    27432785       
    27442786    case GetByOffset: {
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r223318 r223523  
    239239    bool handleDOMJITCall(Node* callee, int resultOperand, const DOMJIT::Signature*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
    240240    template<typename ChecksFunctor>
    241     bool handleIntrinsicGetter(int resultOperand, const GetByIdVariant& intrinsicVariant, Node* thisNode, const ChecksFunctor& insertChecks);
     241    bool handleIntrinsicGetter(int resultOperand, SpeculatedType prediction, const GetByIdVariant& intrinsicVariant, Node* thisNode, const ChecksFunctor& insertChecks);
    242242    template<typename ChecksFunctor>
    243243    bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType, const ChecksFunctor& insertChecks);
     
    26002600    }
    26012601
     2602    case ObjectGetPrototypeOfIntrinsic: {
     2603        if (argumentCountIncludingThis != 2)
     2604            return false;
     2605
     2606        insertChecks();
     2607        set(VirtualRegister(resultOperand), addToGraph(GetPrototypeOf, OpInfo(0), OpInfo(prediction), get(virtualRegisterForArgument(1, registerOffset))));
     2608        return true;
     2609    }
     2610
     2611    case ReflectGetPrototypeOfIntrinsic: {
     2612        if (argumentCountIncludingThis != 2)
     2613            return false;
     2614
     2615        insertChecks();
     2616        set(VirtualRegister(resultOperand), addToGraph(GetPrototypeOf, OpInfo(0), OpInfo(prediction), Edge(get(virtualRegisterForArgument(1, registerOffset)), ObjectUse)));
     2617        return true;
     2618    }
     2619
    26022620    case IsTypedArrayViewIntrinsic: {
    26032621        ASSERT(argumentCountIncludingThis == 2);
     
    29472965
    29482966template<typename ChecksFunctor>
    2949 bool ByteCodeParser::handleIntrinsicGetter(int resultOperand, const GetByIdVariant& variant, Node* thisNode, const ChecksFunctor& insertChecks)
     2967bool ByteCodeParser::handleIntrinsicGetter(int resultOperand, SpeculatedType prediction, const GetByIdVariant& variant, Node* thisNode, const ChecksFunctor& insertChecks)
    29502968{
    29512969    switch (variant.intrinsic()) {
     
    30113029        set(VirtualRegister(resultOperand), addToGraph(GetTypedArrayByteOffset, OpInfo(ArrayMode(arrayType).asWord()), thisNode));
    30123030
     3031        return true;
     3032    }
     3033
     3034    case UnderscoreProtoIntrinsic: {
     3035        insertChecks();
     3036
     3037        bool canFold = !variant.structureSet().isEmpty();
     3038        JSValue prototype;
     3039        variant.structureSet().forEach([&] (Structure* structure) {
     3040            auto getPrototypeMethod = structure->classInfo()->methodTable.getPrototype;
     3041            MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
     3042            if (getPrototypeMethod != defaultGetPrototype) {
     3043                canFold = false;
     3044                return;
     3045            }
     3046
     3047            if (structure->hasPolyProto()) {
     3048                canFold = false;
     3049                return;
     3050            }
     3051            if (!prototype)
     3052                prototype = structure->storedPrototype();
     3053            else if (prototype != structure->storedPrototype())
     3054                canFold = false;
     3055        });
     3056
     3057        // OK, only one prototype is found. We perform constant folding here.
     3058        // This information is important for super's constructor call to get new.target constant.
     3059        if (prototype && canFold) {
     3060            set(VirtualRegister(resultOperand), weakJSConstant(prototype));
     3061            return true;
     3062        }
     3063
     3064        set(VirtualRegister(resultOperand), addToGraph(GetPrototypeOf, OpInfo(0), OpInfo(prediction), thisNode));
    30133065        return true;
    30143066    }
     
    37973849    Node* getter = addToGraph(GetGetter, loadedValue);
    37983850
    3799     if (handleIntrinsicGetter(destinationOperand, variant, base,
     3851    if (handleIntrinsicGetter(destinationOperand, prediction, variant, base,
    38003852            [&] () {
    38013853                addToGraph(CheckCell, OpInfo(m_graph.freeze(variant.intrinsicFunction())), getter);
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r223318 r223523  
    11151115        def(HeapLocation(TypedArrayByteOffsetLoc, MiscFields, node->child1()), LazyNode(node));
    11161116        return;
     1117
     1118    case GetPrototypeOf: {
     1119        switch (node->child1().useKind()) {
     1120        case ArrayUse:
     1121        case FunctionUse:
     1122        case FinalObjectUse:
     1123            read(JSCell_structureID);
     1124            read(JSObject_butterfly);
     1125            read(NamedProperties); // Poly proto could load prototype from its slot.
     1126            def(HeapLocation(PrototypeLoc, NamedProperties, node->child1()), LazyNode(node));
     1127            return;
     1128        default:
     1129            read(World);
     1130            write(Heap);
     1131            return;
     1132        }
     1133    }
    11171134       
    11181135    case GetByOffset:
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r223318 r223523  
    239239    case StringCharCodeAt:
    240240    case GetTypedArrayByteOffset:
     241    case GetPrototypeOf:
    241242    case PutByValDirect:
    242243    case PutByVal:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r223318 r223523  
    16011601            fixEdge<Int32Use>(node->child1());
    16021602            fixEdge<Int32Use>(node->child2());
     1603            break;
     1604        }
     1605
     1606        case GetPrototypeOf: {
     1607            fixupGetPrototypeOf(node);
    16031608            break;
    16041609        }
     
    23032308    }
    23042309
     2310    void fixupGetPrototypeOf(Node* node)
     2311    {
     2312        // Reflect.getPrototypeOf only accepts Objects. For Reflect.getPrototypeOf, ByteCodeParser attaches ObjectUse edge filter before fixup phase.
     2313        if (node->child1().useKind() != ObjectUse) {
     2314            if (node->child1()->shouldSpeculateString()) {
     2315                insertCheck<StringUse>(node->child1().node());
     2316                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->stringPrototype()));
     2317                return;
     2318            }
     2319            if (node->child1()->shouldSpeculateInt32()) {
     2320                insertCheck<Int32Use>(node->child1().node());
     2321                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
     2322                return;
     2323            }
     2324            if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
     2325                insertCheck<Int52RepUse>(node->child1().node());
     2326                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
     2327                return;
     2328            }
     2329            if (node->child1()->shouldSpeculateNumber()) {
     2330                insertCheck<NumberUse>(node->child1().node());
     2331                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->numberPrototype()));
     2332                return;
     2333            }
     2334            if (node->child1()->shouldSpeculateSymbol()) {
     2335                insertCheck<SymbolUse>(node->child1().node());
     2336                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->symbolPrototype()));
     2337                return;
     2338            }
     2339            if (node->child1()->shouldSpeculateBoolean()) {
     2340                insertCheck<BooleanUse>(node->child1().node());
     2341                m_graph.convertToConstant(node, m_graph.freeze(m_graph.globalObjectFor(node->origin.semantic)->booleanPrototype()));
     2342                return;
     2343            }
     2344        }
     2345
     2346        if (node->child1()->shouldSpeculateFinalObject()) {
     2347            fixEdge<FinalObjectUse>(node->child1());
     2348            node->clearFlags(NodeMustGenerate);
     2349            return;
     2350        }
     2351        if (node->child1()->shouldSpeculateArray()) {
     2352            fixEdge<ArrayUse>(node->child1());
     2353            node->clearFlags(NodeMustGenerate);
     2354            return;
     2355        }
     2356        if (node->child1()->shouldSpeculateFunction()) {
     2357            fixEdge<FunctionUse>(node->child1());
     2358            node->clearFlags(NodeMustGenerate);
     2359            return;
     2360        }
     2361    }
     2362
    23052363    void fixupToThis(Node* node)
    23062364    {
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp

    r221959 r223523  
    152152        out.print("TypedArrayByteOffsetLoc");
    153153        return;
     154
     155    case PrototypeLoc:
     156        out.print("PrototypeLoc");
     157        return;
    154158       
    155159    case StructureLoc:
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h

    r221959 r223523  
    6161    StructureLoc,
    6262    TypedArrayByteOffsetLoc,
     63    PrototypeLoc,
    6364    StackLoc,
    6465    StackPayloadLoc,
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r222384 r223523  
    15491549        case GetByIdFlush:
    15501550        case GetByIdWithThis:
     1551        case GetPrototypeOf:
    15511552        case TryGetById:
    15521553        case GetByVal:
     
    23122313    }
    23132314
     2315    bool shouldSpeculateFunction()
     2316    {
     2317        return isFunctionSpeculation(prediction());
     2318    }
     2319
    23142320    bool shouldSpeculateProxyObject()
    23152321    {
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r223318 r223523  
    252252    macro(CheckSubClass, NodeMustGenerate) \
    253253    macro(ParseInt, NodeMustGenerate | NodeResultJS) \
     254    macro(GetPrototypeOf, NodeMustGenerate | NodeResultJS) \
    254255    \
    255256    /* Atomics object functions. */\
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r223125 r223523  
    5353#include "JSFixedArray.h"
    5454#include "JSGenericTypedArrayViewConstructorInlines.h"
     55#include "JSGlobalObjectFunctions.h"
    5556#include "JSLexicalEnvironment.h"
    5657#include "JSMap.h"
     
    25192520}
    25202521
     2522EncodedJSValue JIT_OPERATION operationGetPrototypeOfObject(ExecState* exec, JSObject* thisObject)
     2523{
     2524    VM& vm = exec->vm();
     2525    NativeCallFrameTracer tracer(&vm, exec);
     2526    return JSValue::encode(thisObject->getPrototype(vm, exec));
     2527}
     2528
     2529EncodedJSValue JIT_OPERATION operationGetPrototypeOf(ExecState* exec, EncodedJSValue encodedValue)
     2530{
     2531    VM& vm = exec->vm();
     2532    NativeCallFrameTracer tracer(&vm, exec);
     2533    auto scope = DECLARE_THROW_SCOPE(vm);
     2534
     2535    JSValue thisValue = JSValue::decode(encodedValue).toThis(exec, StrictMode);
     2536    if (thisValue.isUndefinedOrNull())
     2537        return throwVMError(exec, scope, createNotAnObjectError(exec, thisValue));
     2538
     2539    JSObject* thisObject = jsDynamicCast<JSObject*>(vm, thisValue);
     2540    if (!thisObject) {
     2541        JSObject* prototype = thisValue.synthesizePrototype(exec);
     2542        EXCEPTION_ASSERT(!!scope.exception() == !prototype);
     2543        if (UNLIKELY(!prototype))
     2544            return JSValue::encode(JSValue());
     2545        return JSValue::encode(prototype);
     2546    }
     2547
     2548    scope.release();
     2549    return JSValue::encode(thisObject->getPrototype(vm, exec));
     2550}
     2551
    25212552void JIT_OPERATION operationThrowDFG(ExecState* exec, EncodedJSValue valueToThrow)
    25222553{
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r223047 r223523  
    7878EncodedJSValue JIT_OPERATION operationGetByIdWithThis(ExecState*, EncodedJSValue, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
    7979EncodedJSValue JIT_OPERATION operationGetByValWithThis(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
     80EncodedJSValue JIT_OPERATION operationGetPrototypeOf(ExecState*, EncodedJSValue) WTF_INTERNAL;
     81EncodedJSValue JIT_OPERATION operationGetPrototypeOfObject(ExecState*, JSObject*) WTF_INTERNAL;
    8082char* JIT_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF_INTERNAL;
    8183char* JIT_OPERATION operationNewArrayBuffer(ExecState*, Structure*, size_t, size_t) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r223318 r223523  
    724724        case CallDOMGetter:
    725725        case GetDynamicVar:
    726         case WeakMapGet: {
     726        case WeakMapGet:
     727        case GetPrototypeOf: {
    727728            setPrediction(m_currentNode->getHeapPrediction());
    728729            break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r223318 r223523  
    402402    case ForwardVarargs:
    403403    case CreateRest:
     404    case GetPrototypeOf:
    404405    case StringReplace:
    405406    case StringReplaceRegExp:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r223318 r223523  
    91879187}
    91889188
     9189void SpeculativeJIT::speculateFunction(Edge edge, GPRReg cell)
     9190{
     9191    speculateCellType(edge, cell, SpecFunction, JSFunctionType);
     9192}
     9193
    91899194void SpeculativeJIT::speculateFunction(Edge edge)
    91909195{
     
    91939198   
    91949199    SpeculateCellOperand operand(this, edge);
    9195     speculateCellType(edge, operand.gpr(), SpecFunction, JSFunctionType);
     9200    speculateFunction(edge, operand.gpr());
     9201}
     9202
     9203void SpeculativeJIT::speculateFinalObject(Edge edge, GPRReg cell)
     9204{
     9205    speculateCellType(edge, cell, SpecFinalObject, FinalObjectType);
    91969206}
    91979207
     
    92029212   
    92039213    SpeculateCellOperand operand(this, edge);
    9204     speculateCellType(edge, operand.gpr(), SpecFinalObject, FinalObjectType);
     9214    speculateFinalObject(edge, operand.gpr());
    92059215}
    92069216
     
    1076810778}
    1076910779
     10780void SpeculativeJIT::compileGetPrototypeOf(Node* node)
     10781{
     10782    switch (node->child1().useKind()) {
     10783    case ArrayUse:
     10784    case FunctionUse:
     10785    case FinalObjectUse: {
     10786        SpeculateCellOperand object(this, node->child1());
     10787        GPRTemporary temp(this);
     10788        GPRTemporary temp2(this);
     10789
     10790        GPRReg objectGPR = object.gpr();
     10791        GPRReg tempGPR = temp.gpr();
     10792        GPRReg temp2GPR = temp2.gpr();
     10793
     10794        switch (node->child1().useKind()) {
     10795        case ArrayUse:
     10796            speculateArray(node->child1(), objectGPR);
     10797            break;
     10798        case FunctionUse:
     10799            speculateFunction(node->child1(), objectGPR);
     10800            break;
     10801        case FinalObjectUse:
     10802            speculateFinalObject(node->child1(), objectGPR);
     10803            break;
     10804        default:
     10805            RELEASE_ASSERT_NOT_REACHED();
     10806            break;
     10807        }
     10808
     10809        m_jit.emitLoadStructure(*m_jit.vm(), objectGPR, tempGPR, temp2GPR);
     10810
     10811        AbstractValue& value = m_state.forNode(node->child1());
     10812        if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
     10813            bool hasPolyProto = false;
     10814            bool hasMonoProto = false;
     10815            value.m_structure.forEach([&] (RegisteredStructure structure) {
     10816                if (structure->hasPolyProto())
     10817                    hasPolyProto = true;
     10818                else
     10819                    hasMonoProto = true;
     10820            });
     10821
     10822            if (hasMonoProto && !hasPolyProto) {
     10823#if USE(JSVALUE64)
     10824                m_jit.load64(MacroAssembler::Address(tempGPR, Structure::prototypeOffset()), tempGPR);
     10825                jsValueResult(tempGPR, node);
     10826#else
     10827                m_jit.load32(MacroAssembler::Address(tempGPR, Structure::prototypeOffset() + TagOffset), temp2GPR);
     10828                m_jit.load32(MacroAssembler::Address(tempGPR, Structure::prototypeOffset() + PayloadOffset), tempGPR);
     10829                jsValueResult(temp2GPR, tempGPR, node);
     10830#endif
     10831                return;
     10832            }
     10833
     10834            if (hasPolyProto && !hasMonoProto) {
     10835#if USE(JSVALUE64)
     10836                m_jit.load64(MacroAssembler::Address(tempGPR, Structure::prototypeOffset()), tempGPR);
     10837                m_jit.zeroExtend32ToPtr(tempGPR, tempGPR);
     10838                m_jit.load64(JITCompiler::BaseIndex(objectGPR, tempGPR, JITCompiler::TimesEight, JSObject::offsetOfInlineStorage()), tempGPR);
     10839                jsValueResult(tempGPR, node);
     10840#else
     10841                m_jit.load32(MacroAssembler::Address(tempGPR, Structure::prototypeOffset() + PayloadOffset), tempGPR);
     10842                m_jit.load32(JITCompiler::BaseIndex(objectGPR, tempGPR, JITCompiler::TimesEight, JSObject::offsetOfInlineStorage() + TagOffset), temp2GPR);
     10843                m_jit.load32(JITCompiler::BaseIndex(objectGPR, tempGPR, JITCompiler::TimesEight, JSObject::offsetOfInlineStorage() + PayloadOffset), tempGPR);
     10844                jsValueResult(temp2GPR, tempGPR, node);
     10845#endif
     10846                return;
     10847            }
     10848        }
     10849
     10850#if USE(JSVALUE64)
     10851        m_jit.load64(MacroAssembler::Address(tempGPR, Structure::prototypeOffset()), tempGPR);
     10852        auto isMonoProto = m_jit.branchIfNotInt32(JSValueRegs(tempGPR));
     10853        m_jit.zeroExtend32ToPtr(tempGPR, tempGPR);
     10854        m_jit.load64(JITCompiler::BaseIndex(objectGPR, tempGPR, JITCompiler::TimesEight, JSObject::offsetOfInlineStorage()), tempGPR);
     10855        isMonoProto.link(&m_jit);
     10856        jsValueResult(tempGPR, node);
     10857#else
     10858        m_jit.load32(MacroAssembler::Address(tempGPR, Structure::prototypeOffset() + TagOffset), temp2GPR);
     10859        m_jit.load32(MacroAssembler::Address(tempGPR, Structure::prototypeOffset() + PayloadOffset), tempGPR);
     10860        auto isMonoProto = m_jit.branch32(CCallHelpers::NotEqual, temp2GPR, TrustedImm32(JSValue::Int32Tag));
     10861        m_jit.load32(JITCompiler::BaseIndex(objectGPR, tempGPR, JITCompiler::TimesEight, JSObject::offsetOfInlineStorage() + TagOffset), temp2GPR);
     10862        m_jit.load32(JITCompiler::BaseIndex(objectGPR, tempGPR, JITCompiler::TimesEight, JSObject::offsetOfInlineStorage() + PayloadOffset), tempGPR);
     10863        isMonoProto.link(&m_jit);
     10864        jsValueResult(temp2GPR, tempGPR, node);
     10865#endif
     10866        return;
     10867    }
     10868    case ObjectUse: {
     10869        SpeculateCellOperand value(this, node->child1());
     10870        JSValueRegsTemporary result(this);
     10871
     10872        GPRReg valueGPR = value.gpr();
     10873        JSValueRegs resultRegs = result.regs();
     10874
     10875        speculateObject(node->child1(), valueGPR);
     10876
     10877        flushRegisters();
     10878        callOperation(operationGetPrototypeOfObject, resultRegs, valueGPR);
     10879        m_jit.exceptionCheck();
     10880        jsValueResult(resultRegs, node);
     10881        return;
     10882    }
     10883    default: {
     10884        JSValueOperand value(this, node->child1());
     10885        JSValueRegsTemporary result(this);
     10886
     10887        JSValueRegs valueRegs = value.jsValueRegs();
     10888        JSValueRegs resultRegs = result.regs();
     10889
     10890        flushRegisters();
     10891        callOperation(operationGetPrototypeOf, resultRegs, valueRegs);
     10892        m_jit.exceptionCheck();
     10893        jsValueResult(resultRegs, node);
     10894        return;
     10895    }
     10896    }
     10897}
     10898
    1077010899} } // namespace JSC::DFG
    1077110900
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r223318 r223523  
    988988        return appendCallSetResult(operation, result);
    989989    }
     990    JITCompiler::Call callOperation(J_JITOperation_EO operation, JSValueRegs result, GPRReg object)
     991    {
     992        m_jit.setupArgumentsWithExecState(object);
     993        return appendCallSetResult(operation, result);
     994    }
    990995    JITCompiler::Call callOperation(P_JITOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
    991996    {
     
    28362841    void compileLoadKeyFromMapBucket(Node*);
    28372842    void compileLoadValueFromMapBucket(Node*);
     2843    void compileGetPrototypeOf(Node*);
    28382844   
    28392845#if USE(JSVALUE32_64)
     
    30853091    void speculateArray(Edge, GPRReg cell);
    30863092    void speculateArray(Edge);
     3093    void speculateFunction(Edge, GPRReg cell);
    30873094    void speculateFunction(Edge);
     3095    void speculateFinalObject(Edge, GPRReg cell);
    30883096    void speculateFinalObject(Edge);
    30893097    void speculateRegExpObject(Edge, GPRReg cell);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r223318 r223523  
    44334433    case GetTypedArrayByteOffset: {
    44344434        compileGetTypedArrayByteOffset(node);
     4435        break;
     4436    }
     4437
     4438    case GetPrototypeOf: {
     4439        compileGetPrototypeOf(node);
    44354440        break;
    44364441    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r223318 r223523  
    46514651        break;
    46524652    }
     4653
     4654    case GetPrototypeOf: {
     4655        compileGetPrototypeOf(node);
     4656        break;
     4657    }
    46534658       
    46544659    case GetByOffset:
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r223318 r223523  
    145145    case NukeStructureAndSetButterfly:
    146146    case GetTypedArrayByteOffset:
     147    case GetPrototypeOf:
    147148    case NotifyWrite:
    148149    case StoreBarrier:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r223318 r223523  
    822822            compileGetTypedArrayByteOffset();
    823823            break;
     824        case GetPrototypeOf:
     825            compileGetPrototypeOf();
     826            break;
    824827        case AllocatePropertyStorage:
    825828            compileAllocatePropertyStorage();
     
    34293432
    34303433        setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, wastefulOut)));
     3434    }
     3435
     3436    void compileGetPrototypeOf()
     3437    {
     3438        switch (m_node->child1().useKind()) {
     3439        case ArrayUse:
     3440        case FunctionUse:
     3441        case FinalObjectUse: {
     3442            LValue object = lowCell(m_node->child1());
     3443            switch (m_node->child1().useKind()) {
     3444            case ArrayUse:
     3445                speculateArray(m_node->child1(), object);
     3446                break;
     3447            case FunctionUse:
     3448                speculateFunction(m_node->child1(), object);
     3449                break;
     3450            case FinalObjectUse:
     3451                speculateFinalObject(m_node->child1(), object);
     3452                break;
     3453            default:
     3454                RELEASE_ASSERT_NOT_REACHED();
     3455                break;
     3456            }
     3457
     3458            LValue structure = loadStructure(object);
     3459
     3460            AbstractValue& value = m_state.forNode(m_node->child1());
     3461            if ((value.m_type && !(value.m_type & ~SpecObject)) && value.m_structure.isFinite()) {
     3462                bool hasPolyProto = false;
     3463                bool hasMonoProto = false;
     3464                value.m_structure.forEach([&] (RegisteredStructure structure) {
     3465                    if (structure->hasPolyProto())
     3466                        hasPolyProto = true;
     3467                    else
     3468                        hasMonoProto = true;
     3469                });
     3470
     3471                if (hasMonoProto && !hasPolyProto) {
     3472                    setJSValue(m_out.load64(structure, m_heaps.Structure_prototype));
     3473                    return;
     3474                }
     3475
     3476                if (hasPolyProto && !hasMonoProto) {
     3477                    LValue prototypeBits = m_out.load64(structure, m_heaps.Structure_prototype);
     3478                    LValue index = m_out.bitAnd(prototypeBits, m_out.constInt64(UINT_MAX));
     3479                    setJSValue(m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), object, index, ScaleEight, JSObject::offsetOfInlineStorage())));
     3480                    return;
     3481                }
     3482            }
     3483
     3484            LBasicBlock continuation = m_out.newBlock();
     3485            LBasicBlock loadPolyProto = m_out.newBlock();
     3486
     3487            LValue prototypeBits = m_out.load64(structure, m_heaps.Structure_prototype);
     3488            ValueFromBlock directPrototype = m_out.anchor(prototypeBits);
     3489            m_out.branch(isInt32(prototypeBits), unsure(loadPolyProto), unsure(continuation));
     3490
     3491            LBasicBlock lastNext = m_out.appendTo(loadPolyProto, continuation);
     3492            LValue index = m_out.bitAnd(prototypeBits, m_out.constInt64(UINT_MAX));
     3493            ValueFromBlock polyProto = m_out.anchor(
     3494                m_out.load64(m_out.baseIndex(m_heaps.properties.atAnyNumber(), object, index, ScaleEight, JSObject::offsetOfInlineStorage())));
     3495            m_out.jump(continuation);
     3496
     3497            m_out.appendTo(continuation, lastNext);
     3498            setJSValue(m_out.phi(Int64, directPrototype, polyProto));
     3499            return;
     3500        }
     3501        case ObjectUse: {
     3502            setJSValue(vmCall(Int64, m_out.operation(operationGetPrototypeOfObject), m_callFrame, lowObject(m_node->child1())));
     3503            return;
     3504        }
     3505        default: {
     3506            setJSValue(vmCall(Int64, m_out.operation(operationGetPrototypeOf), m_callFrame, lowJSValue(m_node->child1())));
     3507            return;
     3508        }
     3509        }
    34313510    }
    34323511   
     
    90049083
    90059084        LValue prototypeBits = m_out.load64(structure, m_heaps.Structure_prototype);
    9006         ValueFromBlock directProtoype = m_out.anchor(prototypeBits);
     9085        ValueFromBlock directPrototype = m_out.anchor(prototypeBits);
    90079086        m_out.branch(isInt32(prototypeBits), unsure(loadPolyProto), unsure(comparePrototype));
    90089087
     
    90149093
    90159094        m_out.appendTo(comparePrototype, notYetInstance);
    9016         LValue currentPrototype = m_out.phi(Int64, directProtoype, polyProto);
     9095        LValue currentPrototype = m_out.phi(Int64, directPrototype, polyProto);
    90179096        ValueFromBlock isInstanceResult = m_out.anchor(m_out.booleanTrue);
    90189097        m_out.branch(
  • trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp

    r212453 r223523  
    6464        return true;
    6565    }
     66    case UnderscoreProtoIntrinsic: {
     67        auto getPrototypeMethod = structure->classInfo()->methodTable.getPrototype;
     68        MethodTable::GetPrototypeFunctionPtr defaultGetPrototype = JSObject::getPrototype;
     69        return getPrototypeMethod == defaultGetPrototype;
     70    }
    6671    default:
    6772        return false;
     
    126131    }
    127132
     133    case UnderscoreProtoIntrinsic: {
     134        if (structure()->hasMonoProto()) {
     135            jit.moveValue(structure()->storedPrototype(), valueRegs);
     136            state.succeed();
     137            return;
     138        }
     139        // FIXME: Support poly proto for intrinsic getters.
     140        // https://bugs.webkit.org/show_bug.cgi?id=177318
     141        jit.loadValue(MacroAssembler::Address(baseGPR, sizeof(EncodedJSValue) * structure()->polyProtoOffset() + JSObject::offsetOfInlineStorage()), valueRegs);
     142        state.succeed();
     143        return;
     144    }
     145
    128146    default:
    129147        break;
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r222675 r223523  
    177177typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EZZ)(ExecState*, int32_t, int32_t);
    178178typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EZSymtabJ)(ExecState*, int32_t, SymbolTable*, EncodedJSValue);
     179typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EO)(ExecState*, JSObject*);
    179180typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EOIUi)(ExecState*, JSObject*, UniquedStringImpl*, uint32_t);
    180181typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJI)(ExecState*, EncodedJSValue, EncodedJSValue, UniquedStringImpl*);
  • trunk/Source/JavaScriptCore/runtime/Intrinsic.cpp

    r221959 r223523  
    112112    case RegExpTestFastIntrinsic:
    113113        return "RegExpTestFastIntrinsic";
     114    case ObjectGetPrototypeOfIntrinsic:
     115        return "ObjectGetPrototypeOfIntrinsic";
     116    case ReflectGetPrototypeOfIntrinsic:
     117        return "ReflectGetPrototypeOfIntrinsic";
    114118    case StringPrototypeValueOfIntrinsic:
    115119        return "StringPrototypeValueOfIntrinsic";
     
    190194    case TypedArrayByteOffsetIntrinsic:
    191195        return "TypedArrayByteOffsetIntrinsic";
     196    case UnderscoreProtoIntrinsic:
     197        return "UnderscoreProtoIntrinsic";
    192198    case DFGTrueIntrinsic:
    193199        return "DFGTrueIntrinsic";
  • trunk/Source/JavaScriptCore/runtime/Intrinsic.h

    r221959 r223523  
    6969    RegExpTestIntrinsic,
    7070    RegExpTestFastIntrinsic,
     71    ObjectGetPrototypeOfIntrinsic,
     72    ReflectGetPrototypeOfIntrinsic,
    7173    StringPrototypeValueOfIntrinsic,
    7274    StringPrototypeReplaceIntrinsic,
     
    110112    TypedArrayByteLengthIntrinsic,
    111113    TypedArrayByteOffsetIntrinsic,
     114    UnderscoreProtoIntrinsic,
    112115
    113116    // Debugging intrinsics. These are meant to be used as testing hacks within
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r223173 r223523  
    450450    m_objectPrototype.set(vm, this, ObjectPrototype::create(vm, this, ObjectPrototype::createStructure(vm, this, jsNull())));
    451451    GetterSetter* protoAccessor = GetterSetter::create(vm, this);
    452     protoAccessor->setGetter(vm, this, JSFunction::create(vm, this, 0, makeString("get ", vm.propertyNames->underscoreProto.string()), globalFuncProtoGetter));
     452    protoAccessor->setGetter(vm, this, JSFunction::create(vm, this, 0, makeString("get ", vm.propertyNames->underscoreProto.string()), globalFuncProtoGetter, UnderscoreProtoIntrinsic));
    453453    protoAccessor->setSetter(vm, this, JSFunction::create(vm, this, 0, makeString("set ", vm.propertyNames->underscoreProto.string()), globalFuncProtoSetter));
    454454    m_objectPrototype->putDirectNonIndexAccessor(vm, vm.propertyNames->underscoreProto, protoAccessor, PropertyAttribute::Accessor | PropertyAttribute::DontEnum);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r223237 r223523  
    6565namespace JSC {
    6666
    67 static const char* const ObjectProtoCalledOnNullOrUndefinedError = "Object.prototype.__proto__ called on null or undefined";
     67const char* const ObjectProtoCalledOnNullOrUndefinedError = "Object.prototype.__proto__ called on null or undefined";
    6868
    6969template<unsigned charactersCount>
     
    707707    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
    708708    if (thisValue.isUndefinedOrNull())
    709         return throwVMTypeError(exec, scope, ASCIILiteral(ObjectProtoCalledOnNullOrUndefinedError));
     709        return throwVMError(exec, scope, createNotAnObjectError(exec, thisValue));
    710710
    711711    JSObject* thisObject = jsDynamicCast<JSObject*>(vm, thisValue);
    712712    if (!thisObject) {
    713         JSObject* prototype = exec->thisValue().synthesizePrototype(exec);
     713        JSObject* prototype = thisValue.synthesizePrototype(exec);
    714714        EXCEPTION_ASSERT(!!scope.exception() == !prototype);
    715715        if (UNLIKELY(!prototype))
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h

    r218794 r223523  
    3636// is a 0.5% reduction.
    3737
     38extern const char* const ObjectProtoCalledOnNullOrUndefinedError;
     39
    3840EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState*);
    3941EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState*);
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r222473 r223523  
    6868/* Source for ObjectConstructor.lut.h
    6969@begin objectConstructorTable
    70   getPrototypeOf            objectConstructorGetPrototypeOf             DontEnum|Function 1
     70  getPrototypeOf            objectConstructorGetPrototypeOf             DontEnum|Function 1 ObjectGetPrototypeOfIntrinsic
    7171  setPrototypeOf            objectConstructorSetPrototypeOf             DontEnum|Function 2
    7272  getOwnPropertyDescriptor  objectConstructorGetOwnPropertyDescriptor   DontEnum|Function 2
  • trunk/Source/JavaScriptCore/runtime/ReflectObject.cpp

    r222473 r223523  
    6464    get                      reflectObjectGet                      DontEnum|Function 2
    6565    getOwnPropertyDescriptor reflectObjectGetOwnPropertyDescriptor DontEnum|Function 2
    66     getPrototypeOf           reflectObjectGetPrototypeOf           DontEnum|Function 1
     66    getPrototypeOf           reflectObjectGetPrototypeOf           DontEnum|Function 1 ReflectGetPrototypeOfIntrinsic
    6767    has                      JSBuiltin                             DontEnum|Function 2
    6868    isExtensible             reflectObjectIsExtensible             DontEnum|Function 1
Note: See TracChangeset for help on using the changeset viewer.