Changeset 180550 in webkit


Ignore:
Timestamp:
Feb 23, 2015 9:47:22 PM (9 years ago)
Author:
Yusuke Suzuki
Message:

Constructor returning null should construct an object instead of null
https://bugs.webkit.org/show_bug.cgi?id=141640

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

When constructor code doesn't return object, constructor should return this object instead.
Since we used op_is_object for this check and op_is_object is intended to be used for typeof,
it allows null as an object.
This patch fixes it by introducing an new bytecode op_is_object_or_null for typeof use cases.
Instead, constructor uses simplified is_object.

As a result, op_is_object becomes fairly simple. So we introduce optimization for op_is_object.

  1. LLInt and baseline JIT support op_is_object as a fast path.
  2. DFG abstract interpreter support op_is_object. And recognize its speculated type and read-write effects.
  3. DFG introduces inlined asm for op_is_object rather than calling a C++ function.
  4. FTL lowers DFG's IsObject into LLVM IR.

And at the same time, this patch fixes isString / isObject predicate used for op_is_object and others
in LLInt, JIT, DFG and FTL.
Before introducing ES6 Symbol, JSCell is only used for object and string in user observable area.
So in many places, when the cell is not object, we recognize it as a string, and vice versa.
However, now ES6 Symbol is implemented as a JSCell, this assumption is broken.
So this patch stop using !isString as isObject.
To check whether a cell is an object, instead of seeing that structure ID of a cell is not stringStructure,
we examine typeInfo in JSCell.

  • JavaScriptCore.order:
  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):

  • bytecode/PutByIdStatus.cpp:

(JSC::PutByIdStatus::computeFor):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitEqualityOp):
(JSC::BytecodeGenerator::emitReturn):

  • dfg/DFGAbstractInterpreterInlines.h:

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

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCapabilities.cpp:

(JSC::DFG::capabilityLevel):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

IsObject operation only touches JSCell typeInfoType.
And this value would not be changed through structure transition.
As a result, IsObject can report that it doesn't read any information.

  • dfg/DFGDoesGC.cpp:

(JSC::DFG::doesGC):

  • dfg/DFGFixupPhase.cpp:

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

Just like IsString, IsObject is also fixed up.

  • dfg/DFGHeapLocation.cpp:

(WTF::printInternal):

  • dfg/DFGHeapLocation.h:
  • 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::compilePeepHoleObjectEquality):
(JSC::DFG::SpeculativeJIT::compileStringToUntypedEquality):
(JSC::DFG::SpeculativeJIT::compileStringIdentToNotStringVarEquality):
(JSC::DFG::SpeculativeJIT::compileToStringOnCell):
(JSC::DFG::SpeculativeJIT::speculateObject):
(JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
(JSC::DFG::SpeculativeJIT::speculateString):
(JSC::DFG::SpeculativeJIT::speculateNotStringVar):
(JSC::DFG::SpeculativeJIT::emitSwitchChar):
(JSC::DFG::SpeculativeJIT::emitSwitchString):
(JSC::DFG::SpeculativeJIT::branchIsObject):
(JSC::DFG::SpeculativeJIT::branchNotObject):
(JSC::DFG::SpeculativeJIT::branchIsString):
(JSC::DFG::SpeculativeJIT::branchNotString):

  • dfg/DFGSpeculativeJIT.h:
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compileObjectEquality):
(JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
(JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileToString):
(JSC::FTL::LowerDFGToLLVM::compileIsObject):
(JSC::FTL::LowerDFGToLLVM::compileIsObjectOrNull):
(JSC::FTL::LowerDFGToLLVM::speculateTruthyObject):
(JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
(JSC::FTL::LowerDFGToLLVM::isObject):
(JSC::FTL::LowerDFGToLLVM::isNotObject):
(JSC::FTL::LowerDFGToLLVM::isNotString):
(JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • jit/JIT.h:
  • jit/JITInlines.h:

(JSC::JIT::emitJumpIfCellObject):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_is_object):
(JSC::JIT::emit_op_to_primitive):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_is_object):
(JSC::JIT::emit_op_to_primitive):
(JSC::JIT::compileOpStrictEq):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • runtime/CommonSlowPaths.cpp:

(JSC::SLOW_PATH_DECL):

  • runtime/CommonSlowPaths.h:
  • runtime/Operations.cpp:

(JSC::jsIsObjectTypeOrNull):
(JSC::jsIsObjectType): Deleted.

  • runtime/Operations.h:

LayoutTests:

  • js/dfg-to-primitive-pass-symbol-expected.txt: Added.
  • js/dfg-to-primitive-pass-symbol.html: Added.
  • js/dom/constructor-with-return-masquerades-expected.txt: Added.
  • js/dom/constructor-with-return-masquerades.html: Added.
  • js/dom/script-tests/constructor-with-return-masquerades.js: Added.

(Constructor):

Follow the old ret_object_or_this semantics.
When constructor returns an object that masquerades as undefined, we see it as an object.

  • js/regress/constructor-with-return-expected.txt: Added.
  • js/regress/constructor-with-return.html: Added.
  • js/regress/script-tests/constructor-with-return.js: Added.

(Test):

When constructor doesn't return an object, this should be returned instead.
In this test, we check all primitives. And test object, array and wrappers.

  • js/script-tests/dfg-to-primitive-pass-symbol.js: Added.

(toPrimitiveTarget):
(doToPrimitive):

op_to_primitive operation passes Symbol in fast path.

Location:
trunk
Files:
9 added
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r180549 r180550  
     12015-02-23  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Constructor returning null should construct an object instead of null
     4        https://bugs.webkit.org/show_bug.cgi?id=141640
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        * js/dfg-to-primitive-pass-symbol-expected.txt: Added.
     9        * js/dfg-to-primitive-pass-symbol.html: Added.
     10        * js/dom/constructor-with-return-masquerades-expected.txt: Added.
     11        * js/dom/constructor-with-return-masquerades.html: Added.
     12        * js/dom/script-tests/constructor-with-return-masquerades.js: Added.
     13        (Constructor):
     14
     15        Follow the old ret_object_or_this semantics.
     16        When constructor returns an object that masquerades as undefined, we see it as an object.
     17
     18        * js/regress/constructor-with-return-expected.txt: Added.
     19        * js/regress/constructor-with-return.html: Added.
     20        * js/regress/script-tests/constructor-with-return.js: Added.
     21        (Test):
     22
     23        When constructor doesn't return an object, `this` should be returned instead.
     24        In this test, we check all primitives. And test object, array and wrappers.
     25
     26        * js/script-tests/dfg-to-primitive-pass-symbol.js: Added.
     27        (toPrimitiveTarget):
     28        (doToPrimitive):
     29
     30        op_to_primitive operation passes Symbol in fast path.
     31
    1322015-02-23  Ryosuke Niwa  <rniwa@webkit.org>
    233
  • trunk/Source/JavaScriptCore/ChangeLog

    r180549 r180550  
     12015-02-23  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        Constructor returning null should construct an object instead of null
     4        https://bugs.webkit.org/show_bug.cgi?id=141640
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        When constructor code doesn't return object, constructor should return `this` object instead.
     9        Since we used `op_is_object` for this check and `op_is_object` is intended to be used for `typeof`,
     10        it allows `null` as an object.
     11        This patch fixes it by introducing an new bytecode `op_is_object_or_null` for `typeof` use cases.
     12        Instead, constructor uses simplified `is_object`.
     13
     14        As a result, `op_is_object` becomes fairly simple. So we introduce optimization for `op_is_object`.
     15
     16        1. LLInt and baseline JIT support `op_is_object` as a fast path.
     17        2. DFG abstract interpreter support `op_is_object`. And recognize its speculated type and read-write effects.
     18        3. DFG introduces inlined asm for `op_is_object` rather than calling a C++ function.
     19        4. FTL lowers DFG's IsObject into LLVM IR.
     20
     21        And at the same time, this patch fixes isString / isObject predicate used for `op_is_object` and others
     22        in LLInt, JIT, DFG and FTL.
     23        Before introducing ES6 Symbol, JSCell is only used for object and string in user observable area.
     24        So in many places, when the cell is not object, we recognize it as a string, and vice versa.
     25        However, now ES6 Symbol is implemented as a JSCell, this assumption is broken.
     26        So this patch stop using !isString as isObject.
     27        To check whether a cell is an object, instead of seeing that structure ID of a cell is not stringStructure,
     28        we examine typeInfo in JSCell.
     29
     30        * JavaScriptCore.order:
     31        * bytecode/BytecodeList.json:
     32        * bytecode/BytecodeUseDef.h:
     33        (JSC::computeUsesForBytecodeOffset):
     34        (JSC::computeDefsForBytecodeOffset):
     35        * bytecode/CodeBlock.cpp:
     36        (JSC::CodeBlock::dumpBytecode):
     37        * bytecode/PutByIdStatus.cpp:
     38        (JSC::PutByIdStatus::computeFor):
     39        * bytecompiler/BytecodeGenerator.cpp:
     40        (JSC::BytecodeGenerator::emitEqualityOp):
     41        (JSC::BytecodeGenerator::emitReturn):
     42        * dfg/DFGAbstractInterpreterInlines.h:
     43        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     44        * dfg/DFGByteCodeParser.cpp:
     45        (JSC::DFG::ByteCodeParser::parseBlock):
     46        * dfg/DFGCapabilities.cpp:
     47        (JSC::DFG::capabilityLevel):
     48        * dfg/DFGClobberize.h:
     49        (JSC::DFG::clobberize):
     50
     51        IsObject operation only touches JSCell typeInfoType.
     52        And this value would not be changed through structure transition.
     53        As a result, IsObject can report that it doesn't read any information.
     54
     55        * dfg/DFGDoesGC.cpp:
     56        (JSC::DFG::doesGC):
     57        * dfg/DFGFixupPhase.cpp:
     58        (JSC::DFG::FixupPhase::fixupNode):
     59
     60        Just like IsString, IsObject is also fixed up.
     61
     62        * dfg/DFGHeapLocation.cpp:
     63        (WTF::printInternal):
     64        * dfg/DFGHeapLocation.h:
     65        * dfg/DFGNodeType.h:
     66        * dfg/DFGOperations.cpp:
     67        * dfg/DFGOperations.h:
     68        * dfg/DFGPredictionPropagationPhase.cpp:
     69        (JSC::DFG::PredictionPropagationPhase::propagate):
     70        * dfg/DFGSafeToExecute.h:
     71        (JSC::DFG::safeToExecute):
     72        * dfg/DFGSpeculativeJIT.cpp:
     73        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
     74        (JSC::DFG::SpeculativeJIT::compileStringToUntypedEquality):
     75        (JSC::DFG::SpeculativeJIT::compileStringIdentToNotStringVarEquality):
     76        (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
     77        (JSC::DFG::SpeculativeJIT::speculateObject):
     78        (JSC::DFG::SpeculativeJIT::speculateObjectOrOther):
     79        (JSC::DFG::SpeculativeJIT::speculateString):
     80        (JSC::DFG::SpeculativeJIT::speculateNotStringVar):
     81        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
     82        (JSC::DFG::SpeculativeJIT::emitSwitchString):
     83        (JSC::DFG::SpeculativeJIT::branchIsObject):
     84        (JSC::DFG::SpeculativeJIT::branchNotObject):
     85        (JSC::DFG::SpeculativeJIT::branchIsString):
     86        (JSC::DFG::SpeculativeJIT::branchNotString):
     87        * dfg/DFGSpeculativeJIT.h:
     88        * dfg/DFGSpeculativeJIT32_64.cpp:
     89        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
     90        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
     91        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
     92        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
     93        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
     94        (JSC::DFG::SpeculativeJIT::compile):
     95        * dfg/DFGSpeculativeJIT64.cpp:
     96        (JSC::DFG::SpeculativeJIT::compileObjectEquality):
     97        (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality):
     98        (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
     99        (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot):
     100        (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
     101        (JSC::DFG::SpeculativeJIT::compile):
     102        * ftl/FTLCapabilities.cpp:
     103        (JSC::FTL::canCompile):
     104        * ftl/FTLLowerDFGToLLVM.cpp:
     105        (JSC::FTL::LowerDFGToLLVM::compileNode):
     106        (JSC::FTL::LowerDFGToLLVM::compileToString):
     107        (JSC::FTL::LowerDFGToLLVM::compileIsObject):
     108        (JSC::FTL::LowerDFGToLLVM::compileIsObjectOrNull):
     109        (JSC::FTL::LowerDFGToLLVM::speculateTruthyObject):
     110        (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
     111        (JSC::FTL::LowerDFGToLLVM::isObject):
     112        (JSC::FTL::LowerDFGToLLVM::isNotObject):
     113        (JSC::FTL::LowerDFGToLLVM::isNotString):
     114        (JSC::FTL::LowerDFGToLLVM::speculateNonNullObject):
     115        * jit/JIT.cpp:
     116        (JSC::JIT::privateCompileMainPass):
     117        * jit/JIT.h:
     118        * jit/JITInlines.h:
     119        (JSC::JIT::emitJumpIfCellObject):
     120        * jit/JITOpcodes.cpp:
     121        (JSC::JIT::emit_op_is_object):
     122        (JSC::JIT::emit_op_to_primitive):
     123        * jit/JITOpcodes32_64.cpp:
     124        (JSC::JIT::emit_op_is_object):
     125        (JSC::JIT::emit_op_to_primitive):
     126        (JSC::JIT::compileOpStrictEq):
     127        * llint/LowLevelInterpreter.asm:
     128        * llint/LowLevelInterpreter32_64.asm:
     129        * llint/LowLevelInterpreter64.asm:
     130        * runtime/CommonSlowPaths.cpp:
     131        (JSC::SLOW_PATH_DECL):
     132        * runtime/CommonSlowPaths.h:
     133        * runtime/Operations.cpp:
     134        (JSC::jsIsObjectTypeOrNull):
     135        (JSC::jsIsObjectType): Deleted.
     136        * runtime/Operations.h:
     137
    11382015-02-23  Ryosuke Niwa  <rniwa@webkit.org>
    2139
  • trunk/Source/JavaScriptCore/JavaScriptCore.order

    r180547 r180550  
    13491349__ZN3JSC11PostfixNode11emitResolveERNS_17BytecodeGeneratorEPNS_10RegisterIDE
    13501350__ZN3JSC17BytecodeGenerator7emitIncEPNS_10RegisterIDE
    1351 __ZN3JSC14jsIsObjectTypeEPNS_9ExecStateENS_7JSValueE
    13521351__ZN3JSC6JSCell11getCallDataEPS0_RNS_8CallDataE
    13531352__ZN3JSC8JSObject16getPropertyNamesEPS0_PNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
     
    16661665_cti_op_stricteq
    16671666_cti_op_jtrue
    1668 _cti_op_is_object
     1667_cti_op_is_object_or_null
    16691668__ZN3JSC8JSString12toThisObjectEPNS_6JSCellEPNS_9ExecStateE
    16701669__ZN3JSC12StringObjectC1ERNS_2VMEPNS_9StructureE
     
    29642963__ZN3WTF15BinarySemaphore4waitEd
    29652964__ZN3WTF15BinarySemaphore6signalEv
    2966 _JSValueIsObject
    29672965__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateE
    29682966__ZN3JSC5shiftILNS_7JSArray14ShiftCountModeE0EEEvPNS_9ExecStateEPNS_8JSObjectEjjjj
     
    33913389__ZN3JSC8JSObject20ensureContiguousSlowERNS_2VMENS0_22DoubleToContiguousModeE
    33923390_operationMakeRope3
    3393 _operationIsObject
    33943391__ZN3JSC3DFG12slowPathCallINS_22AbstractMacroAssemblerINS_12X86AssemblerEE4JumpEPFxPNS_9ExecStateExPNS_7JSArrayEENS0_11NoResultTagENS_12X86Registers10RegisterIDESE_SE_EEN3WTF10PassOwnPtrINS0_17SlowPathGeneratorEEET_PNS0_14SpeculativeJITET0_T1_T2_T3_T4_NS0_18SpillRegistersModeE
    33953392__ZN3JSC3DFG14SpeculativeJIT13callOperationEPFxPNS_9ExecStateExPNS_7JSArrayEENS_12X86Registers10RegisterIDES9_S9_
     
    48984895_llint_slow_path_instanceof
    48994896_llint_slow_path_typeof
    4900 _llint_slow_path_is_object
     4897_llint_slow_path_is_object_or_null
    49014898_llint_slow_path_is_function
    49024899_llint_slow_path_in
     
    50365033_llint_op_mod
    50375034_llint_op_typeof
    5038 _llint_op_is_object
     5035_llint_op_is_object_or_null
    50395036_llint_op_is_function
    50405037_llint_op_in
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r180514 r180550  
    5454            { "name" : "op_is_string", "length" : 3 },
    5555            { "name" : "op_is_object", "length" : 3 },
     56            { "name" : "op_is_object_or_null", "length" : 3 },
    5657            { "name" : "op_is_function", "length" : 3 },
    5758            { "name" : "op_in", "length" : 4 },
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r179372 r180550  
    134134    case op_is_string:
    135135    case op_is_object:
     136    case op_is_object_or_null:
    136137    case op_is_function:
    137138    case op_to_number:
     
    333334    case op_is_string:
    334335    case op_is_object:
     336    case op_is_object_or_null:
    335337    case op_is_function:
    336338    case op_in:
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r180518 r180550  
    10071007        case op_is_object: {
    10081008            printUnaryOp(out, exec, location, it, "is_object");
     1009            break;
     1010        }
     1011        case op_is_object_or_null: {
     1012            printUnaryOp(out, exec, location, it, "is_object_or_null");
    10091013            break;
    10101014        }
  • trunk/Source/JavaScriptCore/bytecode/PutByIdStatus.cpp

    r178928 r180550  
    361361        // If the structure corresponds to something that isn't an object, then give up, since
    362362        // we don't want to be adding properties to strings.
    363         if (structure->typeInfo().type() == StringType)
     363        if (!structure->typeInfo().isObject())
    364364            return PutByIdStatus(TakesSlowPath);
    365365   
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r180518 r180550  
    10971097            if (value == "object") {
    10981098                rewindUnaryOp();
    1099                 emitOpcode(op_is_object);
     1099                emitOpcode(op_is_object_or_null);
    11001100                instructions().append(dst->index());
    11011101                instructions().append(srcIndex);
     
    19421942
    19431943        size_t begin = instructions().size();
    1944         emitOpcode(op_jtrue);
    1945         instructions().append(isObjectRegister->index());
    1946         instructions().append(isObjectLabel->bind(begin, instructions().size()));
    1947 
    1948         emitOpcode(op_is_function);
    1949         instructions().append(isObjectRegister->index());
    1950         instructions().append(src->index());
    1951 
    1952         begin = instructions().size();
    19531944        emitOpcode(op_jtrue);
    19541945        instructions().append(isObjectRegister->index());
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r180505 r180550  
    801801    case IsString:
    802802    case IsObject:
     803    case IsObjectOrNull:
    803804    case IsFunction: {
    804805        JSValue child = forNode(node->child1()).value();
     
    822823                break;
    823824            case IsObject:
     825                setConstant(node, jsBoolean(child.isObject()));
     826                break;
     827            case IsObjectOrNull:
    824828                if (child.isNull() || !child.isObject()) {
    825829                    setConstant(node, jsBoolean(child.isNull()));
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r180546 r180550  
    28862886            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsObject, value));
    28872887            NEXT_OPCODE(op_is_object);
     2888        }
     2889
     2890        case op_is_object_or_null: {
     2891            Node* value = get(VirtualRegister(currentInstruction[2].u.operand));
     2892            set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(IsObjectOrNull, value));
     2893            NEXT_OPCODE(op_is_object_or_null);
    28882894        }
    28892895
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r180279 r180550  
    133133    case op_is_string:
    134134    case op_is_object:
     135    case op_is_object_or_null:
    135136    case op_is_function:
    136137    case op_not:
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r180279 r180550  
    138138    case IsNumber:
    139139    case IsString:
     140    case IsObject:
    140141    case LogicalNot:
    141142    case CheckInBounds:
     
    341342        return;
    342343       
    343     case IsObject:
     344    case IsObjectOrNull:
    344345        read(MiscFields);
    345         def(HeapLocation(IsObjectLoc, MiscFields, node->child1()), node);
     346        def(HeapLocation(IsObjectOrNullLoc, MiscFields, node->child1()), node);
    346347        return;
    347348       
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r180279 r180550  
    136136    case IsString:
    137137    case IsObject:
     138    case IsObjectOrNull:
    138139    case IsFunction:
    139140    case TypeOf:
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r180279 r180550  
    10901090            break;
    10911091
     1092        case IsObject:
     1093            if (node->child1()->shouldSpeculateObject()) {
     1094                m_insertionSet.insertNode(
     1095                    m_indexInBlock, SpecNone, Phantom, node->origin,
     1096                    Edge(node->child1().node(), ObjectUse));
     1097                m_graph.convertToConstant(node, jsBoolean(true));
     1098                observeUseKindOnNode<ObjectUse>(node);
     1099            }
     1100            break;
     1101
    10921102        case GetEnumerableLength: {
    10931103            fixEdge<CellUse>(node->child1());
     
    12311241        case IsBoolean:
    12321242        case IsNumber:
    1233         case IsObject:
     1243        case IsObjectOrNull:
    12341244        case IsFunction:
    12351245        case CreateArguments:
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.cpp

    r173993 r180550  
    6161        return;
    6262       
    63     case IsObjectLoc:
    64         out.print("IsObjectLoc");
     63    case IsObjectOrNullLoc:
     64        out.print("IsObjectOrNullLoc");
    6565        return;
    66        
     66
    6767    case IsFunctionLoc:
    6868        out.print("IsFunctionLoc");
  • trunk/Source/JavaScriptCore/dfg/DFGHeapLocation.h

    r173993 r180550  
    5151    InvalidationPointLoc,
    5252    IsFunctionLoc,
    53     IsObjectLoc,
     53    IsObjectOrNullLoc,
    5454    MyArgumentByValLoc,
    5555    MyArgumentsLengthLoc,
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r180279 r180550  
    251251    macro(IsString, NodeResultBoolean) \
    252252    macro(IsObject, NodeResultBoolean) \
     253    macro(IsObjectOrNull, NodeResultBoolean) \
    253254    macro(IsFunction, NodeResultBoolean) \
    254255    macro(TypeOf, NodeResultJS) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r180279 r180550  
    809809}
    810810
    811 size_t JIT_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
    812 {
    813     return jsIsObjectType(exec, JSValue::decode(value));
     811size_t JIT_OPERATION operationIsObjectOrNull(ExecState* exec, EncodedJSValue value)
     812{
     813    return jsIsObjectTypeOrNull(exec, JSValue::decode(value));
    814814}
    815815
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.h

    r180279 r180550  
    103103JSCell* JIT_OPERATION operationNewFunctionNoCheck(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
    104104double JIT_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
    105 size_t JIT_OPERATION operationIsObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
     105size_t JIT_OPERATION operationIsObjectOrNull(ExecState*, EncodedJSValue) WTF_INTERNAL;
    106106size_t JIT_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;
    107107JSCell* JIT_OPERATION operationTypeOf(ExecState*, JSCell*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r180279 r180550  
    359359        case IsString:
    360360        case IsObject:
     361        case IsObjectOrNull:
    361362        case IsFunction: {
    362363            changed |= setPrediction(SpecBoolean);
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r180279 r180550  
    211211    case IsString:
    212212    case IsObject:
     213    case IsObjectOrNull:
    213214    case IsFunction:
    214215    case TypeOf:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r180098 r180550  
    11581158        if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
    11591159            speculationCheck(
    1160                 BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
    1161                 m_jit.branchStructurePtr(
    1162                     MacroAssembler::Equal,
    1163                     MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1164                     m_jit.vm()->stringStructure.get()));
     1160                BadType, JSValueSource::unboxedCell(op1GPR), node->child1(), branchNotObject(op1GPR));
    11651161        }
    11661162        if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
    11671163            speculationCheck(
    1168                 BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
    1169                 m_jit.branchStructurePtr(
    1170                     MacroAssembler::Equal,
    1171                     MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1172                     m_jit.vm()->stringStructure.get()));
     1164                BadType, JSValueSource::unboxedCell(op2GPR), node->child2(), branchNotObject(op2GPR));
    11731165        }
    11741166    } else {
    1175         GPRTemporary structure(this);
    1176         GPRTemporary temp(this);
    1177         GPRReg structureGPR = structure.gpr();
    1178 
    1179         m_jit.emitLoadStructure(op1GPR, structureGPR, temp.gpr());
    11801167        if (m_state.forNode(node->child1()).m_type & ~SpecObject) {
    11811168            speculationCheck(
    11821169                BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
    1183                 m_jit.branchPtr(
    1184                     MacroAssembler::Equal,
    1185                     structureGPR,
    1186                     MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1170                branchNotObject(op1GPR));
    11871171        }
    11881172        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
     
    11921176                MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
    11931177
    1194         m_jit.emitLoadStructure(op2GPR, structureGPR, temp.gpr());
    11951178        if (m_state.forNode(node->child2()).m_type & ~SpecObject) {
    11961179            speculationCheck(
    11971180                BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
    1198                 m_jit.branchPtr(
    1199                     MacroAssembler::Equal,
    1200                     structureGPR,
    1201                     MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1181                branchNotObject(op2GPR));
    12021182        }
    12031183        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
     
    39643944        MacroAssembler::Equal, leftGPR, rightRegs.payloadGPR()));
    39653945   
    3966     fastFalse.append(m_jit.branchStructurePtr(
    3967         MacroAssembler::NotEqual,
    3968         MacroAssembler::Address(rightRegs.payloadGPR(), JSCell::structureIDOffset()),
    3969         m_jit.vm()->stringStructure.get()));
     3946    fastFalse.append(branchNotString(rightRegs.payloadGPR()));
    39703947   
    39713948    compileStringEquality(
     
    40153992    JITCompiler::JumpList notString;
    40163993    notString.append(branchNotCell(rightRegs));
    4017     notString.append(m_jit.branchStructurePtr(
    4018         MacroAssembler::NotEqual,
    4019         MacroAssembler::Address(rightRegs.payloadGPR(), JSCell::structureIDOffset()),
    4020         m_jit.vm()->stringStructure.get()));
     3994    notString.append(branchNotString(rightRegs.payloadGPR()));
    40213995   
    40223996    speculateStringIdentAndLoadStorage(notStringVarEdge, rightRegs.payloadGPR(), rightTempGPR);
     
    44614435        m_jit.load32(JITCompiler::Address(op1GPR, JSCell::structureIDOffset()), resultGPR);
    44624436        JITCompiler::Jump isString = m_jit.branchStructurePtr(
    4463             JITCompiler::Equal, 
     4437            JITCompiler::Equal,
    44644438            resultGPR,
    44654439            m_jit.vm()->stringStructure.get());
    4466        
     4440
    44674441        speculateStringObjectForStructure(node->child1(), resultGPR);
    44684442       
     
    44904464        JITCompiler::Jump done;
    44914465        if (node->child1()->prediction() & SpecString) {
    4492             JITCompiler::Jump needCall = m_jit.branchStructurePtr(
    4493                 JITCompiler::NotEqual,
    4494                 JITCompiler::Address(op1GPR, JSCell::structureIDOffset()),
    4495                 m_jit.vm()->stringStructure.get());
     4466            JITCompiler::Jump needCall = branchNotString(op1GPR);
    44964467            m_jit.move(op1GPR, resultGPR);
    44974468            done = m_jit.jump();
     
    47174688    GPRReg gpr = operand.gpr();
    47184689    DFG_TYPE_CHECK(
    4719         JSValueSource::unboxedCell(gpr), edge, SpecObject, m_jit.branchStructurePtr(
    4720             MacroAssembler::Equal,
    4721             MacroAssembler::Address(gpr, JSCell::structureIDOffset()),
    4722             m_jit.vm()->stringStructure.get()));
     4690        JSValueSource::unboxedCell(gpr), edge, SpecObject, branchNotObject(gpr));
    47234691}
    47244692
     
    47524720    GPRReg gpr = operand.jsValueRegs().payloadGPR();
    47534721    DFG_TYPE_CHECK(
    4754         operand.jsValueRegs(), edge, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    4755             MacroAssembler::Equal,
    4756             MacroAssembler::Address(gpr, JSCell::structureIDOffset()),
    4757             m_jit.vm()->stringStructure.get()));
     4722        operand.jsValueRegs(), edge, (~SpecCell) | SpecObject, branchNotObject(gpr));
    47584723    MacroAssembler::Jump done = m_jit.jump();
    47594724    notCell.link(&m_jit);
     
    47694734{
    47704735    DFG_TYPE_CHECK(
    4771         JSValueSource::unboxedCell(cell), edge, SpecString | ~SpecCell,
    4772         m_jit.branchStructurePtr(
    4773             MacroAssembler::NotEqual,
    4774             MacroAssembler::Address(cell, JSCell::structureIDOffset()),
    4775             m_jit.vm()->stringStructure.get()));
     4736        JSValueSource::unboxedCell(cell), edge, SpecString | ~SpecCell, branchNotString(cell));
    47764737}
    47774738
     
    48784839    GPRReg cell = operand.jsValueRegs().payloadGPR();
    48794840   
    4880     JITCompiler::Jump notString = m_jit.branchStructurePtr(
    4881         MacroAssembler::NotEqual,
    4882         MacroAssembler::Address(cell, JSCell::structureIDOffset()),
    4883         m_jit.vm()->stringStructure.get());
     4841    JITCompiler::Jump notString = branchNotString(cell);
    48844842   
    48854843    speculateStringIdentAndLoadStorage(edge, cell, tempGPR);
     
    51575115        addBranch(branchNotCell(op1Regs), data->fallThrough.block);
    51585116       
    5159         addBranch(
    5160             m_jit.branchStructurePtr(
    5161                 MacroAssembler::NotEqual,
    5162                 MacroAssembler::Address(op1Regs.payloadGPR(), JSCell::structureIDOffset()),
    5163                 m_jit.vm()->stringStructure.get()),
    5164             data->fallThrough.block);
     5117        addBranch(branchNotString(op1Regs.payloadGPR()), data->fallThrough.block);
    51655118       
    51665119        emitSwitchCharStringJump(data, op1Regs.payloadGPR(), tempGPR);
     
    54475400        addBranch(branchNotCell(op1Regs), data->fallThrough.block);
    54485401       
    5449         addBranch(
    5450             m_jit.branchStructurePtr(
    5451                 MacroAssembler::NotEqual,
    5452                 MacroAssembler::Address(op1Regs.payloadGPR(), JSCell::structureIDOffset()),
    5453                 m_jit.vm()->stringStructure.get()),
    5454             data->fallThrough.block);
     5402        addBranch(branchNotString(op1Regs.payloadGPR()), data->fallThrough.block);
    54555403       
    54565404        emitSwitchStringOnString(data, op1Regs.payloadGPR());
     
    55005448        branch.jump.linkTo(m_jit.blockHeads()[branch.destination->index], &m_jit);
    55015449    }
     5450}
     5451
     5452JITCompiler::Jump SpeculativeJIT::branchIsObject(GPRReg cellGPR)
     5453{
     5454    return m_jit.branch8(
     5455        MacroAssembler::AboveOrEqual,
     5456        MacroAssembler::Address(cellGPR, JSCell::typeInfoTypeOffset()),
     5457        MacroAssembler::TrustedImm32(ObjectType));
     5458}
     5459
     5460JITCompiler::Jump SpeculativeJIT::branchNotObject(GPRReg cellGPR)
     5461{
     5462    return m_jit.branch8(
     5463        MacroAssembler::Below,
     5464        MacroAssembler::Address(cellGPR, JSCell::typeInfoTypeOffset()),
     5465        MacroAssembler::TrustedImm32(ObjectType));
     5466}
     5467
     5468JITCompiler::Jump SpeculativeJIT::branchIsString(GPRReg cellGPR)
     5469{
     5470    return m_jit.branchStructurePtr(
     5471        MacroAssembler::Equal,
     5472        MacroAssembler::Address(cellGPR, JSCell::structureIDOffset()),
     5473        m_jit.vm()->stringStructure.get());
     5474}
     5475
     5476JITCompiler::Jump SpeculativeJIT::branchNotString(GPRReg cellGPR)
     5477{
     5478    return m_jit.branchStructurePtr(
     5479        MacroAssembler::NotEqual,
     5480        MacroAssembler::Address(cellGPR, JSCell::structureIDOffset()),
     5481        m_jit.vm()->stringStructure.get());
    55025482}
    55035483
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r180345 r180550  
    21922192    JITCompiler::Jump branchIsOther(JSValueRegs, GPRReg tempGPR);
    21932193    JITCompiler::Jump branchNotOther(JSValueRegs, GPRReg tempGPR);
     2194    JITCompiler::Jump branchIsObject(GPRReg cellGPR);
     2195    JITCompiler::Jump branchNotObject(GPRReg cellGPR);
     2196    JITCompiler::Jump branchIsString(GPRReg cellGPR);
     2197    JITCompiler::Jump branchNotString(GPRReg cellGPR);
    21942198   
    21952199    void moveTrueTo(GPRReg);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r180279 r180550  
    12011201    if (masqueradesAsUndefinedWatchpointIsStillValid()) {
    12021202        DFG_TYPE_CHECK(
    1203             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
    1204                 MacroAssembler::Equal,
    1205                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1206                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1203            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, branchNotObject(op1GPR));
    12071204        DFG_TYPE_CHECK(
    1208             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
    1209                 MacroAssembler::Equal,
    1210                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1211                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1205            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, branchNotObject(op2GPR));
    12121206    } else {
    12131207        DFG_TYPE_CHECK(
    1214             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr(
    1215                 MacroAssembler::Equal,
    1216                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1217                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
    1218         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
     1208            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, branchNotObject(op1GPR));
     1209        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
    12191210            m_jit.branchTest8(
    12201211                MacroAssembler::NonZero,
    1221                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
     1212                MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()),
    12221213                MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
    12231214
    12241215        DFG_TYPE_CHECK(
    1225             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchPtr(
    1226                 MacroAssembler::Equal,
    1227                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1228                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
    1229         speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
     1216            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, branchNotObject(op2GPR));
     1217        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
    12301218            m_jit.branchTest8(
    1231                 MacroAssembler::NonZero, 
    1232                 MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()), 
     1219                MacroAssembler::NonZero,
     1220                MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()),
    12331221                MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
    12341222    }
     
    12631251    if (masqueradesAsUndefinedWatchpointValid) {
    12641252        DFG_TYPE_CHECK(
    1265             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
    1266                 MacroAssembler::Equal,
    1267                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1268                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1253            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    12691254    } else {
    12701255        DFG_TYPE_CHECK(
    1271             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
    1272                 MacroAssembler::Equal,
    1273                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1274                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1256            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    12751257        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
    12761258            m_jit.branchTest8(
     
    12881270    if (masqueradesAsUndefinedWatchpointValid) {
    12891271        DFG_TYPE_CHECK(
    1290             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
    1291             m_jit.branchPtr(
    1292                 MacroAssembler::Equal,
    1293                 MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()),
    1294                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1272            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject, branchNotObject(op2PayloadGPR));
    12951273    } else {
    12961274        DFG_TYPE_CHECK(
    1297             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
    1298             m_jit.branchPtr(
    1299                 MacroAssembler::Equal,
    1300                 MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()),
    1301                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1275            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject, branchNotObject(op2PayloadGPR));
    13021276        speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
    13031277            m_jit.branchTest8(
     
    13561330    if (masqueradesAsUndefinedWatchpointValid) {
    13571331        DFG_TYPE_CHECK(
    1358             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
    1359                 MacroAssembler::Equal,
    1360                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1361                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1332            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    13621333    } else {
    13631334        DFG_TYPE_CHECK(
    1364             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr(
    1365                 MacroAssembler::Equal,
    1366                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1367                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1335            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    13681336        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
    13691337            m_jit.branchTest8(
     
    13811349        DFG_TYPE_CHECK(
    13821350            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
    1383             m_jit.branchPtr(
    1384                 MacroAssembler::Equal,
    1385                 MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()),
    1386                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1351            branchNotObject(op2PayloadGPR));
    13871352    } else {
    13881353        DFG_TYPE_CHECK(
    13891354            JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
    1390             m_jit.branchPtr(
    1391                 MacroAssembler::Equal,
    1392                 MacroAssembler::Address(op2PayloadGPR, JSCell::structureIDOffset()),
    1393                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1355            branchNotObject(op2PayloadGPR));
    13941356        speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
    13951357            m_jit.branchTest8(
     
    14751437        DFG_TYPE_CHECK(
    14761438            JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
    1477             m_jit.branchPtr(
    1478                 MacroAssembler::Equal,
    1479                 MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()),
    1480                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1439            branchNotObject(valuePayloadGPR));
    14811440    } else {
    1482         m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), structureGPR);
    1483 
    14841441        DFG_TYPE_CHECK(
    14851442            JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
    1486             m_jit.branchPtr(
    1487                 MacroAssembler::Equal,
    1488                 structureGPR,
    1489                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1443            branchNotObject(valuePayloadGPR));
    14901444
    14911445        MacroAssembler::Jump isNotMasqueradesAsUndefined =
     
    14951449                MacroAssembler::TrustedImm32(MasqueradesAsUndefined));
    14961450
     1451        m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), structureGPR);
    14971452        speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
    14981453            m_jit.branchPtr(
     
    16041559        DFG_TYPE_CHECK(
    16051560            JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
    1606             m_jit.branchPtr(
    1607                 MacroAssembler::Equal,
    1608                 MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()),
    1609                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1561            branchNotObject(valuePayloadGPR));
    16101562    } else {
    1611         m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), scratchGPR);
    1612 
    16131563        DFG_TYPE_CHECK(
    16141564            JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
    1615             m_jit.branchPtr(
    1616                 MacroAssembler::Equal,
    1617                 scratchGPR,
    1618                 MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
     1565            branchNotObject(valuePayloadGPR));
    16191566
    16201567        JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(
     
    16231570            TrustedImm32(MasqueradesAsUndefined));
    16241571
     1572        m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), scratchGPR);
    16251573        speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
    16261574            m_jit.branchPtr(
     
    31663114        } else {
    31673115            MacroAssembler::Jump alreadyPrimitive = branchNotCell(op1.jsValueRegs());
    3168             MacroAssembler::Jump notPrimitive = m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1PayloadGPR, JSCell::structureIDOffset()), MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get()));
     3116            MacroAssembler::Jump notPrimitive = branchIsObject(op1PayloadGPR);
    31693117           
    31703118            alreadyPrimitive.link(&m_jit);
     
    31963144            if (node->child1()->prediction() & SpecString) {
    31973145                JITCompiler::Jump slowPath1 = branchNotCell(op1.jsValueRegs());
    3198                 JITCompiler::Jump slowPath2 = m_jit.branchPtr(
    3199                     JITCompiler::NotEqual,
    3200                     JITCompiler::Address(op1PayloadGPR, JSCell::structureIDOffset()),
    3201                     TrustedImmPtr(m_jit.vm()->stringStructure.get()));
     3146                JITCompiler::Jump slowPath2 = branchNotString(op1PayloadGPR);
    32023147                m_jit.move(op1PayloadGPR, resultGPR);
    32033148                done = m_jit.jump();
     
    42084153    case IsObject: {
    42094154        JSValueOperand value(this, node->child1());
     4155        GPRTemporary result(this, Reuse, value, TagWord);
     4156
     4157        JITCompiler::Jump isNotCell = branchNotCell(value.jsValueRegs());
     4158
     4159        m_jit.compare8(JITCompiler::AboveOrEqual,
     4160            JITCompiler::Address(value.payloadGPR(), JSCell::typeInfoTypeOffset()),
     4161            TrustedImm32(ObjectType),
     4162            result.gpr());
     4163        JITCompiler::Jump done = m_jit.jump();
     4164
     4165        isNotCell.link(&m_jit);
     4166        m_jit.move(TrustedImm32(0), result.gpr());
     4167
     4168        done.link(&m_jit);
     4169        booleanResult(result.gpr(), node);
     4170        break;
     4171    }
     4172
     4173    case IsObjectOrNull: {
     4174        JSValueOperand value(this, node->child1());
    42104175        GPRReg valueTagGPR = value.tagGPR();
    42114176        GPRReg valuePayloadGPR = value.payloadGPR();
     
    42134178        GPRReg resultGPR = result.gpr();
    42144179        flushRegisters();
    4215         callOperation(operationIsObject, resultGPR, valueTagGPR, valuePayloadGPR);
     4180        callOperation(operationIsObjectOrNull, resultGPR, valueTagGPR, valuePayloadGPR);
    42164181        booleanResult(result.gpr(), node);
    42174182        break;
     
    42484213
    42494214        if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
    4250             JITCompiler::Jump notString = m_jit.branch8(
    4251                 JITCompiler::NotEqual,
    4252                 JITCompiler::Address(payloadGPR, JSCell::typeInfoTypeOffset()),
    4253                 TrustedImm32(StringType));
     4215            JITCompiler::Jump notString = branchNotString(payloadGPR);
    42544216            if (node->child1().useKind() == StringUse)
    42554217                DFG_TYPE_CHECK(JSValueRegs(tagGPR, payloadGPR), node->child1(), SpecString, notString);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r180279 r180550  
    13071307    if (masqueradesAsUndefinedWatchpointIsStillValid()) {
    13081308        DFG_TYPE_CHECK(
    1309             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchStructurePtr(
    1310                 MacroAssembler::Equal,
    1311                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1312                 m_jit.vm()->stringStructure.get()));
     1309            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, branchNotObject(op1GPR));
    13131310        DFG_TYPE_CHECK(
    1314             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchStructurePtr(
    1315                 MacroAssembler::Equal,
    1316                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1317                 m_jit.vm()->stringStructure.get()));
     1311            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, branchNotObject(op2GPR));
    13181312    } else {
    13191313        DFG_TYPE_CHECK(
    1320             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchStructurePtr(
    1321                 MacroAssembler::Equal,
    1322                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1323                 m_jit.vm()->stringStructure.get()));
     1314            JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, branchNotObject(op1GPR));
    13241315        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
    13251316            m_jit.branchTest8(
     
    13291320
    13301321        DFG_TYPE_CHECK(
    1331             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchStructurePtr(
    1332                 MacroAssembler::Equal,
    1333                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1334                 m_jit.vm()->stringStructure.get()));
     1322            JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, branchNotObject(op2GPR));
    13351323        speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
    13361324            m_jit.branchTest8(
     
    13651353    if (masqueradesAsUndefinedWatchpointValid) {
    13661354        DFG_TYPE_CHECK(
    1367             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
    1368                 MacroAssembler::Equal,
    1369                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1370                 m_jit.vm()->stringStructure.get()));
     1355            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    13711356    } else {
    13721357        DFG_TYPE_CHECK(
    1373             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
    1374                 MacroAssembler::Equal,
    1375                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1376                 m_jit.vm()->stringStructure.get()));
     1358            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    13771359        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
    13781360            m_jit.branchTest8(
     
    13891371    if (masqueradesAsUndefinedWatchpointValid) {
    13901372        DFG_TYPE_CHECK(
    1391             JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1392                 MacroAssembler::Equal,
    1393                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1394                 m_jit.vm()->stringStructure.get()));
     1373            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, branchNotObject(op2GPR));
    13951374    } else {
    13961375        DFG_TYPE_CHECK(
    1397             JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1398                 MacroAssembler::Equal,
    1399                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1400                 m_jit.vm()->stringStructure.get()));
     1376            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, branchNotObject(op2GPR));
    14011377        speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
    14021378            m_jit.branchTest8(
     
    14551431    if (masqueradesAsUndefinedWatchpointValid) {
    14561432        DFG_TYPE_CHECK(
    1457             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
    1458                 MacroAssembler::Equal,
    1459                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1460                 m_jit.vm()->stringStructure.get()));
     1433            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    14611434    } else {
    14621435        DFG_TYPE_CHECK(
    1463             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchStructurePtr(
    1464                 MacroAssembler::Equal,
    1465                 MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    1466                 m_jit.vm()->stringStructure.get()));
     1436            JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, branchNotObject(op1GPR));
    14671437        speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
    14681438            m_jit.branchTest8(
     
    14791449    if (masqueradesAsUndefinedWatchpointValid) {
    14801450        DFG_TYPE_CHECK(
    1481             JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1482                 MacroAssembler::Equal,
    1483                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1484                 m_jit.vm()->stringStructure.get()));
     1451            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, branchNotObject(op2GPR));
    14851452    } else {
    14861453        DFG_TYPE_CHECK(
    1487             JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1488                 MacroAssembler::Equal,
    1489                 MacroAssembler::Address(op2GPR, JSCell::structureIDOffset()),
    1490                 m_jit.vm()->stringStructure.get()));
     1454            JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, branchNotObject(op2GPR));
    14911455        speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
    14921456            m_jit.branchTest8(
     
    16101574    if (masqueradesAsUndefinedWatchpointValid) {
    16111575        DFG_TYPE_CHECK(
    1612             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1613                 MacroAssembler::Equal,
    1614                 MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()),
    1615                 m_jit.vm()->stringStructure.get()));
     1576            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, branchNotObject(valueGPR));
    16161577    } else {
    16171578        DFG_TYPE_CHECK(
    1618             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1619                 MacroAssembler::Equal,
    1620                 MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()),
    1621                 m_jit.vm()->stringStructure.get()));
     1579            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, branchNotObject(valueGPR));
    16221580
    16231581        MacroAssembler::Jump isNotMasqueradesAsUndefined =
     
    17601718    if (masqueradesAsUndefinedWatchpointIsStillValid()) {
    17611719        DFG_TYPE_CHECK(
    1762             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1763                 MacroAssembler::Equal,
    1764                 MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()),
    1765                 m_jit.vm()->stringStructure.get()));               
     1720            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, branchNotObject(valueGPR));
    17661721    } else {
    17671722        DFG_TYPE_CHECK(
    1768             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchStructurePtr(
    1769                 MacroAssembler::Equal,
    1770                 MacroAssembler::Address(valueGPR, JSCell::structureIDOffset()),
    1771                 m_jit.vm()->stringStructure.get()));
     1723            JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, branchNotObject(valueGPR));
    17721724
    17731725        JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(
     
    32803232       
    32813233        MacroAssembler::Jump alreadyPrimitive = branchNotCell(JSValueRegs(op1GPR));
    3282         MacroAssembler::Jump notPrimitive = m_jit.branchStructurePtr(
    3283             MacroAssembler::NotEqual,
    3284             MacroAssembler::Address(op1GPR, JSCell::structureIDOffset()),
    3285             m_jit.vm()->stringStructure.get());
     3234        MacroAssembler::Jump notPrimitive = branchIsObject(op1GPR);
    32863235       
    32873236        alreadyPrimitive.link(&m_jit);
     
    33083257            if (node->child1()->prediction() & SpecString) {
    33093258                JITCompiler::Jump slowPath1 = branchNotCell(JSValueRegs(op1GPR));
    3310                 JITCompiler::Jump slowPath2 = m_jit.branchStructurePtr(
    3311                     JITCompiler::NotEqual,
    3312                     JITCompiler::Address(op1GPR, JSCell::structureIDOffset()),
    3313                     m_jit.vm()->stringStructure.get());
     3259                JITCompiler::Jump slowPath2 = branchNotString(op1GPR);
    33143260                m_jit.move(op1GPR, resultGPR);
    33153261                done = m_jit.jump();
     
    42634209        break;
    42644210    }
    4265        
     4211
    42664212    case IsObject: {
     4213        JSValueOperand value(this, node->child1());
     4214        GPRTemporary result(this, Reuse, value);
     4215
     4216        JITCompiler::Jump isNotCell = branchNotCell(value.jsValueRegs());
     4217
     4218        m_jit.compare8(JITCompiler::AboveOrEqual,
     4219            JITCompiler::Address(value.gpr(), JSCell::typeInfoTypeOffset()),
     4220            TrustedImm32(ObjectType),
     4221            result.gpr());
     4222        m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
     4223        JITCompiler::Jump done = m_jit.jump();
     4224
     4225        isNotCell.link(&m_jit);
     4226        m_jit.move(TrustedImm32(ValueFalse), result.gpr());
     4227
     4228        done.link(&m_jit);
     4229        jsValueResult(result.gpr(), node, DataFormatJSBoolean);
     4230        break;
     4231    }
     4232
     4233    case IsObjectOrNull: {
    42674234        JSValueOperand value(this, node->child1());
    42684235        GPRReg valueGPR = value.gpr();
     
    42704237        GPRReg resultGPR = result.gpr();
    42714238        flushRegisters();
    4272         callOperation(operationIsObject, resultGPR, valueGPR);
     4239        callOperation(operationIsObjectOrNull, resultGPR, valueGPR);
    42734240        m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
    42744241        jsValueResult(result.gpr(), node, DataFormatJSBoolean);
     
    43044271
    43054272        if (!node->child1()->shouldSpeculateObject() || node->child1().useKind() == StringUse) {
    4306             JITCompiler::Jump notString = m_jit.branch8(
    4307                 JITCompiler::NotEqual,
    4308                 JITCompiler::Address(valueGPR, JSCell::typeInfoTypeOffset()),
    4309                 TrustedImm32(StringType));
     4273            JITCompiler::Jump notString = branchNotString(valueGPR);
    43104274            if (node->child1().useKind() == StringUse)
    43114275                DFG_TYPE_CHECK(JSValueSource(valueGPR), node->child1(), SpecString, notString);
     
    50795043        else if (cachedTypeLocation->m_lastSeenType == TypeString) {
    50805044            MacroAssembler::Jump isNotCell = branchNotCell(JSValueRegs(valueGPR));
    5081             jumpToEnd.append(m_jit.branch8(MacroAssembler::Equal, MacroAssembler::Address(valueGPR, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
     5045            jumpToEnd.append(branchIsString(valueGPR));
    50825046            isNotCell.link(&m_jit);
    50835047        }
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r180279 r180550  
    157157    case IsString:
    158158    case IsObject:
     159    case IsObjectOrNull:
    159160    case IsFunction:
    160161    case CheckHasInstance:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r180360 r180550  
    761761        case IsObject:
    762762            compileIsObject();
     763            break;
     764        case IsObjectOrNull:
     765            compileIsObjectOrNull();
    763766            break;
    764767        case IsFunction:
     
    30973100            LValue isStringPredicate;
    30983101            if (m_node->child1()->prediction() & SpecString) {
    3099                 isStringPredicate = m_out.equal(
    3100                     m_out.load32(value, m_heaps.JSCell_structureID),
    3101                     m_out.constInt32(vm().stringStructure->id()));
     3102                isStringPredicate = isString(value);
    31023103            } else
    31033104                isStringPredicate = m_out.booleanFalse;
     
    42054206        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
    42064207    }
    4207    
     4208
    42084209    void compileIsObject()
    42094210    {
     4211        LValue value = lowJSValue(m_node->child1());
     4212
     4213        LBasicBlock isCellCase = FTL_NEW_BLOCK(m_out, ("IsObject cell case"));
     4214        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("IsObject continuation"));
     4215
     4216        ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
     4217        m_out.branch(isCell(value), unsure(isCellCase), unsure(continuation));
     4218
     4219        LBasicBlock lastNext = m_out.appendTo(isCellCase, continuation);
     4220        ValueFromBlock cellResult = m_out.anchor(isObject(value));
     4221        m_out.jump(continuation);
     4222
     4223        m_out.appendTo(continuation, lastNext);
     4224        setBoolean(m_out.phi(m_out.boolean, notCellResult, cellResult));
     4225    }
     4226
     4227    void compileIsObjectOrNull()
     4228    {
    42104229        LValue pointerResult = vmCall(
    4211             m_out.operation(operationIsObject), m_callFrame, lowJSValue(m_node->child1()));
     4230            m_out.operation(operationIsObjectOrNull), m_callFrame, lowJSValue(m_node->child1()));
    42124231        setBoolean(m_out.notNull(pointerResult));
    42134232    }
     
    51315150        }
    51325151       
    5133         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
    5134         FTL_TYPE_CHECK(
    5135             jsValueValue(cell), edge, filter,
    5136             m_out.equal(structureID, m_out.constInt32(vm().stringStructure->id())));
     5152        FTL_TYPE_CHECK(jsValueValue(cell), edge, filter, isNotObject(cell));
    51375153        speculate(
    51385154            BadType, jsValueValue(cell), edge.node(),
     
    54445460        case CellCaseSpeculatesObject:
    54455461            FTL_TYPE_CHECK(
    5446                 jsValueValue(value), edge, (~SpecCell) | SpecObject,
    5447                 m_out.equal(
    5448                     m_out.load32(value, m_heaps.JSCell_structureID),
    5449                     m_out.constInt32(vm().stringStructure->id())));
     5462                jsValueValue(value), edge, (~SpecCell) | SpecObject, isNotObject(value));
    54505463            break;
    54515464        }
     
    62736286    LValue isObject(LValue cell)
    62746287    {
     6288        return m_out.aboveOrEqual(
     6289            m_out.load8(cell, m_heaps.JSCell_typeInfoType),
     6290            m_out.constInt8(ObjectType));
     6291    }
     6292
     6293    LValue isNotObject(LValue cell)
     6294    {
     6295        return m_out.below(
     6296            m_out.load8(cell, m_heaps.JSCell_typeInfoType),
     6297            m_out.constInt8(ObjectType));
     6298    }
     6299
     6300    LValue isNotString(LValue cell)
     6301    {
    62756302        return m_out.notEqual(
    62766303            m_out.load32(cell, m_heaps.JSCell_structureID),
     
    62786305    }
    62796306   
    6280     LValue isNotString(LValue cell)
    6281     {
    6282         return isObject(cell);
    6283     }
    6284    
    62856307    LValue isString(LValue cell)
    62866308    {
     
    62886310            m_out.load32(cell, m_heaps.JSCell_structureID),
    62896311            m_out.constInt32(vm().stringStructure->id()));
    6290     }
    6291    
    6292     LValue isNotObject(LValue cell)
    6293     {
    6294         return isString(cell);
    62956312    }
    62966313   
     
    64916508    void speculateNonNullObject(Edge edge, LValue cell)
    64926509    {
    6493         FTL_TYPE_CHECK(
    6494             jsValueValue(cell), edge, SpecObject,
    6495             m_out.equal(
    6496                 m_out.load32(cell, m_heaps.JSCell_structureID),
    6497                 m_out.constInt32(vm().stringStructure->id())));
     6510        FTL_TYPE_CHECK(jsValueValue(cell), edge, SpecObject, isNotObject(cell));
    64986511        if (masqueradesAsUndefinedWatchpointIsStillValid())
    64996512            return;
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r180279 r180550  
    186186        DEFINE_SLOW_OP(greatereq)
    187187        DEFINE_SLOW_OP(is_function)
    188         DEFINE_SLOW_OP(is_object)
     188        DEFINE_SLOW_OP(is_object_or_null)
    189189        DEFINE_SLOW_OP(typeof)
    190190
     
    226226        DEFINE_OP(op_is_number)
    227227        DEFINE_OP(op_is_string)
     228        DEFINE_OP(op_is_object)
    228229        DEFINE_OP(op_jeq_null)
    229230        DEFINE_OP(op_jfalse)
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r180514 r180550  
    308308        void emitLoadDouble(int index, FPRegisterID value);
    309309        void emitLoadInt32ToDouble(int index, FPRegisterID value);
     310        Jump emitJumpIfCellObject(RegisterID cellReg);
    310311        Jump emitJumpIfCellNotObject(RegisterID cellReg);
    311312
     
    490491        void emit_op_is_number(Instruction*);
    491492        void emit_op_is_string(Instruction*);
     493        void emit_op_is_object(Instruction*);
    492494        void emit_op_jeq_null(Instruction*);
    493495        void emit_op_jfalse(Instruction*);
  • trunk/Source/JavaScriptCore/jit/JITInlines.h

    r180514 r180550  
    686686}
    687687
     688ALWAYS_INLINE JIT::Jump JIT::emitJumpIfCellObject(RegisterID cellReg)
     689{
     690    return branch8(AboveOrEqual, Address(cellReg, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType));
     691}
     692
    688693ALWAYS_INLINE JIT::Jump JIT::emitJumpIfCellNotObject(RegisterID cellReg)
    689694{
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r180514 r180550  
    227227}
    228228
     229void JIT::emit_op_is_object(Instruction* currentInstruction)
     230{
     231    int dst = currentInstruction[1].u.operand;
     232    int value = currentInstruction[2].u.operand;
     233
     234    emitGetVirtualRegister(value, regT0);
     235    Jump isNotCell = emitJumpIfNotJSCell(regT0);
     236
     237    compare8(AboveOrEqual, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType), regT0);
     238    emitTagAsBoolImmediate(regT0);
     239    Jump done = jump();
     240
     241    isNotCell.link(this);
     242    move(TrustedImm32(ValueFalse), regT0);
     243
     244    done.link(this);
     245    emitPutVirtualRegister(dst);
     246}
     247
    229248void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
    230249{
     
    261280   
    262281    Jump isImm = emitJumpIfNotJSCell(regT0);
    263     addSlowCase(branchStructure(NotEqual,
    264         Address(regT0, JSCell::structureIDOffset()),
    265         m_vm->stringStructure.get()));
     282    addSlowCase(emitJumpIfCellObject(regT0));
    266283    isImm.link(this);
    267284
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r180514 r180550  
    332332}
    333333
     334void JIT::emit_op_is_object(Instruction* currentInstruction)
     335{
     336    int dst = currentInstruction[1].u.operand;
     337    int value = currentInstruction[2].u.operand;
     338
     339    emitLoad(value, regT1, regT0);
     340    Jump isNotCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
     341
     342    compare8(AboveOrEqual, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(ObjectType), regT0);
     343    Jump done = jump();
     344
     345    isNotCell.link(this);
     346    move(TrustedImm32(0), regT0);
     347
     348    done.link(this);
     349    emitStoreBool(dst, regT0);
     350}
     351
    334352void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
    335353{
     
    352370
    353371    Jump isImm = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
    354     addSlowCase(branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
     372    addSlowCase(emitJumpIfCellObject(regT0));
    355373    isImm.link(this);
    356374
     
    625643    addSlowCase(branch32(Below, regT1, TrustedImm32(JSValue::LowestTag)));
    626644
    627     // Jump to a slow case if both are strings.
     645    // Jump to a slow case if both are strings or symbols (non object).
    628646    Jump notCell = branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag));
    629     Jump firstNotString = branchPtr(NotEqual, Address(regT0, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get()));
    630     addSlowCase(branchPtr(Equal, Address(regT2, JSCell::structureIDOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
     647    Jump firstIsObject = emitJumpIfCellObject(regT0);
     648    addSlowCase(emitJumpIfCellNotObject(regT2));
    631649    notCell.link(this);
    632     firstNotString.link(this);
     650    firstIsObject.link(this);
    633651
    634652    // Simply compare the payloads.
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r180514 r180550  
    984984
    985985
    986 _llint_op_is_object:
    987     traceExecution()
    988     callSlowPath(_slow_path_is_object)
     986_llint_op_is_object_or_null:
     987    traceExecution()
     988    callSlowPath(_slow_path_is_object_or_null)
    989989    dispatch(3)
    990 
    991990
    992991_llint_op_is_function:
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

    r180060 r180550  
    953953    bineq t2, t3, .slow
    954954    bib t2, LowestTag, .slow
    955     bineq t2, CellTag, .notString
    956     bbneq JSCell::m_type[t0], StringType, .notString
    957     bbeq JSCell::m_type[t1], StringType, .slow
    958 .notString:
     955    bineq t2, CellTag, .notStringOrSymbol
     956    bbaeq JSCell::m_type[t0], ObjectType, .notStringOrSymbol
     957    bbb JSCell::m_type[t1], ObjectType, .slow
     958.notStringOrSymbol:
    959959    loadi 4[PC], t2
    960960    equalityOperation(t0, t1, t0)
     
    13301330    dispatch(3)
    13311331.opIsStringNotCell:
     1332    storep 0, PayloadOffset[cfr, t2, 8]
     1333    dispatch(3)
     1334
     1335
     1336_llint_op_is_object:
     1337    traceExecution()
     1338    loadi 8[PC], t1
     1339    loadi 4[PC], t2
     1340    loadConstantOrVariable(t1, t0, t3)
     1341    storei BooleanTag, TagOffset[cfr, t2, 8]
     1342    bineq t0, CellTag, .opIsObjectNotCell
     1343    cbaeq JSCell::m_type[t3], ObjectType, t1
     1344    storei t1, PayloadOffset[cfr, t2, 8]
     1345    dispatch(3)
     1346.opIsObjectNotCell:
    13321347    storep 0, PayloadOffset[cfr, t2, 8]
    13331348    dispatch(3)
     
    19771992    loadConstantOrVariable(t2, t1, t0)
    19781993    bineq t1, CellTag, .opToPrimitiveIsImm
    1979     bbneq JSCell::m_type[t0], StringType, .opToPrimitiveSlowCase
     1994    bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
    19801995.opToPrimitiveIsImm:
    19811996    storei t1, TagOffset[cfr, t3, 8]
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

    r180234 r180550  
    12071207
    12081208
     1209_llint_op_is_object:
     1210    traceExecution()
     1211    loadisFromInstruction(2, t1)
     1212    loadisFromInstruction(1, t2)
     1213    loadConstantOrVariable(t1, t0)
     1214    btqnz t0, tagMask, .opIsObjectNotCell
     1215    cbaeq JSCell::m_type[t0], ObjectType, t1
     1216    orq ValueFalse, t1
     1217    storeq t1, [cfr, t2, 8]
     1218    dispatch(3)
     1219.opIsObjectNotCell:
     1220    storeq ValueFalse, [cfr, t2, 8]
     1221    dispatch(3)
     1222
     1223
    12091224macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
    12101225    bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
     
    18351850    loadConstantOrVariable(t2, t0)
    18361851    btqnz t0, tagMask, .opToPrimitiveIsImm
    1837     bbneq JSCell::m_type[t0], StringType, .opToPrimitiveSlowCase
     1852    bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
    18381853.opToPrimitiveIsImm:
    18391854    storeq t0, [cfr, t3, 8]
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp

    r179429 r180550  
    456456}
    457457
    458 SLOW_PATH_DECL(slow_path_is_object)
    459 {
    460     BEGIN();
    461     RETURN(jsBoolean(jsIsObjectType(exec, OP_C(2).jsValue())));
     458SLOW_PATH_DECL(slow_path_is_object_or_null)
     459{
     460    BEGIN();
     461    RETURN(jsBoolean(jsIsObjectTypeOrNull(exec, OP_C(2).jsValue())));
    462462}
    463463
  • trunk/Source/JavaScriptCore/runtime/CommonSlowPaths.h

    r179429 r180550  
    215215SLOW_PATH_HIDDEN_DECL(slow_path_typeof);
    216216SLOW_PATH_HIDDEN_DECL(slow_path_is_object);
     217SLOW_PATH_HIDDEN_DECL(slow_path_is_object_or_null);
    217218SLOW_PATH_HIDDEN_DECL(slow_path_is_function);
    218219SLOW_PATH_HIDDEN_DECL(slow_path_in);
  • trunk/Source/JavaScriptCore/runtime/Operations.cpp

    r179429 r180550  
    8686}
    8787
    88 bool jsIsObjectType(CallFrame* callFrame, JSValue v)
     88bool jsIsObjectTypeOrNull(CallFrame* callFrame, JSValue v)
    8989{
    9090    if (!v.isCell())
  • trunk/Source/JavaScriptCore/runtime/Operations.h

    r178441 r180550  
    3232JSValue jsTypeStringForValue(CallFrame*, JSValue);
    3333JSValue jsTypeStringForValue(VM&, JSGlobalObject*, JSValue);
    34 bool jsIsObjectType(CallFrame*, JSValue);
     34bool jsIsObjectTypeOrNull(CallFrame*, JSValue);
    3535bool jsIsFunctionType(JSValue);
    3636
Note: See TracChangeset for help on using the changeset viewer.