Source/JavaScriptCore/ChangeLog

 12012-04-10 Filip Pizlo <fpizlo@apple.com>
 2
 3 op_is_foo should be optimized
 4 https://bugs.webkit.org/show_bug.cgi?id=83666
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Work in progress. So far I just have op_is_undefined.
 9
 10 * dfg/DFGAbstractState.cpp:
 11 (JSC::DFG::AbstractState::execute):
 12 * dfg/DFGByteCodeParser.cpp:
 13 (JSC::DFG::ByteCodeParser::parseBlock):
 14 * dfg/DFGCSEPhase.cpp:
 15 (JSC::DFG::CSEPhase::performNodeCSE):
 16 * dfg/DFGCapabilities.h:
 17 (JSC::DFG::canCompileOpcode):
 18 * dfg/DFGNodeType.h:
 19 (DFG):
 20 * dfg/DFGPredictionPropagationPhase.cpp:
 21 (JSC::DFG::PredictionPropagationPhase::propagate):
 22 * dfg/DFGSpeculativeJIT32_64.cpp:
 23 (JSC::DFG::SpeculativeJIT::compile):
 24 * dfg/DFGSpeculativeJIT64.cpp:
 25 (JSC::DFG::SpeculativeJIT::compile):
 26 * jit/JIT.cpp:
 27 (JSC::JIT::privateCompileMainPass):
 28 * jit/JIT.h:
 29 (JIT):
 30 * jit/JITOpcodes.cpp:
 31 (JSC::JIT::emit_op_is_undefined):
 32 (JSC):
 33 * jit/JITOpcodes32_64.cpp:
 34 (JSC::JIT::emit_op_is_undefined):
 35 (JSC):
 36 * llint/LLIntSlowPaths.cpp:
 37 (LLInt):
 38 * llint/LLIntSlowPaths.h:
 39 (LLInt):
 40 * llint/LowLevelInterpreter.asm:
 41 * llint/LowLevelInterpreter32_64.asm:
 42 * llint/LowLevelInterpreter64.asm:
 43
1442012-04-10 Mark Rowe <mrowe@apple.com>
245
346 Attempt to fix the Windows build.
113830

Source/JavaScriptCore/dfg/DFGAbstractState.cpp

@@bool AbstractState::execute(unsigned ind
403403 forNode(nodeIndex).set(PredictBoolean);
404404 break;
405405 }
 406
 407 case IsUndefined: {
 408 forNode(nodeIndex).set(PredictBoolean);
 409 break;
 410 }
406411
407412 case CompareLess:
408413 case CompareLessEq:
113828

Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

@@bool ByteCodeParser::parseBlock(unsigned
17271727 set(currentInstruction[1].u.operand, addToGraph(InstanceOf, value, baseValue, prototype));
17281728 NEXT_OPCODE(op_instanceof);
17291729 }
 1730
 1731 case op_is_undefined: {
 1732 NodeIndex value = get(currentInstruction[2].u.operand);
 1733 set(currentInstruction[1].u.operand, addToGraph(IsUndefined, value));
 1734 NEXT_OPCODE(op_is_undefined);
 1735 }
17301736
17311737 case op_not: {
17321738 NodeIndex value = get(currentInstruction[2].u.operand);
113828

Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

@@private:
588588 case StringCharAt:
589589 case StringCharCodeAt:
590590 case Int32ToDouble:
 591 case IsUndefined:
591592 setReplacement(pureCSE(node));
592593 break;
593594
113828

Source/JavaScriptCore/dfg/DFGCapabilities.h

@@inline bool canCompileOpcode(OpcodeID op
9696 case op_mov:
9797 case op_check_has_instance:
9898 case op_instanceof:
 99 case op_is_undefined:
99100 case op_not:
100101 case op_less:
101102 case op_lesseq:
113828

Source/JavaScriptCore/dfg/DFGNodeType.h

@@namespace JSC { namespace DFG {
170170 macro(Breakpoint, NodeMustGenerate | NodeClobbersWorld) \
171171 macro(CheckHasInstance, NodeMustGenerate) \
172172 macro(InstanceOf, NodeResultBoolean) \
 173 macro(IsUndefined, NodeResultBoolean) \
173174 macro(LogicalNot, NodeResultBoolean | NodeMightClobber) \
174175 macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
175176 macro(StrCat, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
113828

Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

@@private:
379379 case CompareGreaterEq:
380380 case CompareEq:
381381 case CompareStrictEq:
382  case InstanceOf: {
 382 case InstanceOf:
 383 case IsUndefined: {
383384 changed |= setPrediction(PredictBoolean);
384385 changed |= mergeDefaultFlags(node);
385386 break;
113828

Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

@@void SpeculativeJIT::compile(Node& node)
35923592 break;
35933593 }
35943594
 3595 case IsUndefined: {
 3596 JSValueOperand value(this, node.child1());
 3597 GPRTemporary result(this);
 3598
 3599 JITCompiler::Jump isCell = m_jit.branch32(JITCompiler::Equal, value.tagGPR(), JITCompiler::TrustedImm32(JSValue::CellTag));
 3600
 3601 m_jit.compare32(JITCompiler::Equal, value.tagGPR(), TrustedImm32(JSValue::UndefinedTag), result.gpr());
 3602 JITCompiler::Jump done = m_jit.jump();
 3603
 3604 isCell.link(&m_jit);
 3605 m_jit.loadPtr(JITCompiler::Address(value.payloadGPR(), JSCell::structureOffset()), result.gpr());
 3606 m_jit.test8(JITCompiler::NonZero, JITCompiler::Address(result.gpr(), Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), result.gpr());
 3607
 3608 done.link(&m_jit);
 3609 booleanResult(result.gpr(), m_compileIndex);
 3610 break;
 3611 }
 3612
35953613 case Phi:
35963614 case Flush:
35973615 break;
113828

Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

@@void SpeculativeJIT::compile(Node& node)
35633563 compileInstanceOf(node);
35643564 break;
35653565 }
 3566
 3567 case IsUndefined: {
 3568 JSValueOperand value(this, node.child1());
 3569 GPRTemporary result(this);
 3570
 3571 JITCompiler::Jump isCell = m_jit.branchTestPtr(JITCompiler::Zero, value.gpr(), GPRInfo::tagMaskRegister);
 3572
 3573 m_jit.comparePtr(JITCompiler::Equal, value.gpr(), TrustedImm32(ValueUndefined), result.gpr());
 3574 JITCompiler::Jump done = m_jit.jump();
 3575
 3576 isCell.link(&m_jit);
 3577 m_jit.loadPtr(JITCompiler::Address(value.gpr(), JSCell::structureOffset()), result.gpr());
 3578 m_jit.test8(JITCompiler::NonZero, JITCompiler::Address(result.gpr(), Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), result.gpr());
 3579
 3580 done.link(&m_jit);
 3581 m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
 3582 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
 3583 break;
 3584 }
35663585
35673586 case Flush:
35683587 case Phi:
113828

Source/JavaScriptCore/jit/JIT.cpp

@@void JIT::privateCompileMainPass()
234234 DEFINE_UNARY_OP(op_is_number)
235235 DEFINE_UNARY_OP(op_is_object)
236236 DEFINE_UNARY_OP(op_is_string)
237  DEFINE_UNARY_OP(op_is_undefined)
238237 DEFINE_UNARY_OP(op_typeof)
239238
240239 DEFINE_OP(op_add)

@@void JIT::privateCompileMainPass()
269268 DEFINE_OP(op_get_scoped_var)
270269 DEFINE_OP(op_check_has_instance)
271270 DEFINE_OP(op_instanceof)
 271 DEFINE_OP(op_is_undefined)
272272 DEFINE_OP(op_jeq_null)
273273 DEFINE_OP(op_jfalse)
274274 DEFINE_OP(op_jmp)
113828

Source/JavaScriptCore/jit/JIT.h

@@namespace JSC {
804804 void emit_op_init_lazy_reg(Instruction*);
805805 void emit_op_check_has_instance(Instruction*);
806806 void emit_op_instanceof(Instruction*);
 807 void emit_op_is_undefined(Instruction*);
807808 void emit_op_jeq_null(Instruction*);
808809 void emit_op_jfalse(Instruction*);
809810 void emit_op_jmp(Instruction*);
113828

Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

@@void JIT::emitSlow_op_instanceof(Instruc
631631 stubCall.call(dst);
632632}
633633
 634void JIT::emit_op_is_undefined(Instruction* currentInstruction)
 635{
 636 unsigned dst = currentInstruction[1].u.operand;
 637 unsigned value = currentInstruction[2].u.operand;
 638
 639 emitLoad(value, regT1, regT0);
 640 Jump isCell = branch(Equal, regT1, TrustedImm32(JSValue::CellTag));
 641
 642 compare32(Equal, regT1, TrustedImm32(JSValue::UndefinedTag), regT0);
 643 Jump done = jump();
 644
 645 isCell.link(this);
 646 loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
 647 test8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
 648
 649 done.link(this);
 650 emitStoreBool(dst, regT0);
 651}
 652
634653void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
635654{
636655 unsigned activation = currentInstruction[1].u.operand;
113828

Source/JavaScriptCore/jit/JITOpcodes.cpp

@@void JIT::emit_op_instanceof(Instruction
465465 emitPutVirtualRegister(dst);
466466}
467467
 468void JIT::emit_op_is_undefined(Instruction* currentInstruction)
 469{
 470 unsigned dst = currentInstruction[1].u.operand;
 471 unsigned value = currentInstruction[2].u.operand;
 472
 473 emitGetVirtualRegister(value, regT0);
 474 Jump isCell = emitJumpIfJSCell(regT0);
 475
 476 comparePtr(Equal, regT0, TrustedImm32(ValueUndefined), regT0);
 477 Jump done = jump();
 478
 479 isCell.link(this);
 480 loadPtr(Address(regT0, JSCell::structureOffset()), regT1);
 481 test8(NonZero, Address(regT1, Structure::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined), regT0);
 482
 483 done.link(this);
 484 emitTagAsBoolImmediate(regT0);
 485 emitPutVirtualRegister(dst);
 486}
 487
468488void JIT::emit_op_call(Instruction* currentInstruction)
469489{
470490 compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++);
113828

Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

@@LLINT_SLOW_PATH_DECL(slow_path_typeof)
702702 LLINT_RETURN(jsTypeStringForValue(exec, LLINT_OP_C(2).jsValue()));
703703}
704704
705 LLINT_SLOW_PATH_DECL(slow_path_is_undefined)
706 {
707  LLINT_BEGIN();
708  JSValue v = LLINT_OP_C(2).jsValue();
709  LLINT_RETURN(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
710 }
711 
712705LLINT_SLOW_PATH_DECL(slow_path_is_boolean)
713706{
714707 LLINT_BEGIN();
113828

Source/JavaScriptCore/llint/LLIntSlowPaths.h

@@LLINT_SLOW_PATH_DECL(slow_path_bitxor);
132132LLINT_SLOW_PATH_DECL(slow_path_check_has_instance);
133133LLINT_SLOW_PATH_DECL(slow_path_instanceof);
134134LLINT_SLOW_PATH_DECL(slow_path_typeof);
135 LLINT_SLOW_PATH_DECL(slow_path_is_undefined);
136135LLINT_SLOW_PATH_DECL(slow_path_is_boolean);
137136LLINT_SLOW_PATH_DECL(slow_path_is_number);
138137LLINT_SLOW_PATH_DECL(slow_path_is_string);
113828

Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm

@@_llint_op_instanceof:
862862 dispatch(5)
863863
864864
 865_llint_op_is_undefined:
 866 traceExecution()
 867 loadi 8[PC], t1
 868 loadi 4[PC], t0
 869 loadConstantOrVariable(t1, t2, t3)
 870 storei BooleanTag, TagOffset[cfr, t0, 8]
 871 bieq t2, CellTag, .opIsUndefinedCell
 872 cieq t2, UndefinedTag, t3
 873 storei t3, PayloadOffset[cfr, t0, 8]
 874 dispatch(3)
 875.opIsUndefinedCell:
 876 loadp JSCell::m_structure[t3], t1
 877 tbnz Structure::m_typeInfo + TypeInfo::m_flags[t1], MasqueradesAsUndefined, t1
 878 storei t1, PayloadOffset[cfr, t0, 8]
 879 dispatch(3)
 880
 881
865882macro resolveGlobal(size, slow)
866883 # Operands are as follows:
867884 # 4[PC] Destination for the load.
113828

Source/JavaScriptCore/llint/LowLevelInterpreter64.asm

@@_llint_op_instanceof:
732732 dispatch(5)
733733
734734
 735_llint_op_is_undefined:
 736 traceExecution()
 737 loadis 16[PB, PC, 8], t1
 738 loadis 8[PB, PC, 8], t2
 739 loadConstantOrVariable(t1, t0)
 740 btpz t0, tagMask, .opIsUndefinedCell
 741 cpeq t0, ValueUndefined, t3
 742 orp ValueFalse, t3
 743 storep t3, [cfr, t2, 8]
 744 dispatch(3)
 745.opIsUndefinedCell:
 746 loadp JSCell::m_structure[t0], t0
 747 tbnz Structure::m_typeInfo + TypeInfo::m_flags[t0], MasqueradesAsUndefined, t1
 748 orp ValueFalse, t1
 749 storep t1, [cfr, t2, 8]
 750 dispatch(3)
 751
 752
735753macro resolveGlobal(size, slow)
736754 # Operands are as follows:
737755 # 8[PB, PC, 8] Destination for the load.
113828

Source/JavaScriptCore/llint/LowLevelInterpreter.asm

@@_llint_op_typeof:
423423 dispatch(3)
424424
425425
426 _llint_op_is_undefined:
427  traceExecution()
428  callSlowPath(_llint_slow_path_is_undefined)
429  dispatch(3)
430 
431 
432426_llint_op_is_boolean:
433427 traceExecution()
434428 callSlowPath(_llint_slow_path_is_boolean)
113828