| OLD | NEW | 
|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 //     * Redistributions of source code must retain the above copyright | 6 //     * Redistributions of source code must retain the above copyright | 
| 7 //       notice, this list of conditions and the following disclaimer. | 7 //       notice, this list of conditions and the following disclaimer. | 
| 8 //     * Redistributions in binary form must reproduce the above | 8 //     * Redistributions in binary form must reproduce the above | 
| 9 //       copyright notice, this list of conditions and the following | 9 //       copyright notice, this list of conditions and the following | 
| 10 //       disclaimer in the documentation and/or other materials provided | 10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 538 | 538 | 
| 539   if (FLAG_deopt_every_n_times != 0) { | 539   if (FLAG_deopt_every_n_times != 0) { | 
| 540     Handle<SharedFunctionInfo> shared(info_->shared_info()); | 540     Handle<SharedFunctionInfo> shared(info_->shared_info()); | 
| 541     Label no_deopt; | 541     Label no_deopt; | 
| 542     __ pushfd(); | 542     __ pushfd(); | 
| 543     __ push(eax); | 543     __ push(eax); | 
| 544     __ push(ebx); | 544     __ push(ebx); | 
| 545     __ mov(ebx, shared); | 545     __ mov(ebx, shared); | 
| 546     __ mov(eax, FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset)); | 546     __ mov(eax, FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset)); | 
| 547     __ sub(Operand(eax), Immediate(Smi::FromInt(1))); | 547     __ sub(Operand(eax), Immediate(Smi::FromInt(1))); | 
| 548     __ j(not_zero, &no_deopt); | 548     __ j(not_zero, &no_deopt, Label::kNear); | 
| 549     if (FLAG_trap_on_deopt) __ int3(); | 549     if (FLAG_trap_on_deopt) __ int3(); | 
| 550     __ mov(eax, Immediate(Smi::FromInt(FLAG_deopt_every_n_times))); | 550     __ mov(eax, Immediate(Smi::FromInt(FLAG_deopt_every_n_times))); | 
| 551     __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax); | 551     __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax); | 
| 552     __ pop(ebx); | 552     __ pop(ebx); | 
| 553     __ pop(eax); | 553     __ pop(eax); | 
| 554     __ popfd(); | 554     __ popfd(); | 
| 555     __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 555     __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 
| 556 | 556 | 
| 557     __ bind(&no_deopt); | 557     __ bind(&no_deopt); | 
| 558     __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax); | 558     __ mov(FieldOperand(ebx, SharedFunctionInfo::kDeoptCounterOffset), eax); | 
| 559     __ pop(ebx); | 559     __ pop(ebx); | 
| 560     __ pop(eax); | 560     __ pop(eax); | 
| 561     __ popfd(); | 561     __ popfd(); | 
| 562   } | 562   } | 
| 563 | 563 | 
| 564   if (cc == no_condition) { | 564   if (cc == no_condition) { | 
| 565     if (FLAG_trap_on_deopt) __ int3(); | 565     if (FLAG_trap_on_deopt) __ int3(); | 
| 566     __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 566     __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 
| 567   } else { | 567   } else { | 
| 568     if (FLAG_trap_on_deopt) { | 568     if (FLAG_trap_on_deopt) { | 
| 569       NearLabel done; | 569       Label done; | 
| 570       __ j(NegateCondition(cc), &done); | 570       __ j(NegateCondition(cc), &done, Label::kNear); | 
| 571       __ int3(); | 571       __ int3(); | 
| 572       __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 572       __ jmp(entry, RelocInfo::RUNTIME_ENTRY); | 
| 573       __ bind(&done); | 573       __ bind(&done); | 
| 574     } else { | 574     } else { | 
| 575       __ j(cc, entry, RelocInfo::RUNTIME_ENTRY, not_taken); | 575       __ j(cc, entry, RelocInfo::RUNTIME_ENTRY, not_taken); | 
| 576     } | 576     } | 
| 577   } | 577   } | 
| 578 } | 578 } | 
| 579 | 579 | 
| 580 | 580 | 
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 780 | 780 | 
| 781 void LCodeGen::DoModI(LModI* instr) { | 781 void LCodeGen::DoModI(LModI* instr) { | 
| 782   if (instr->hydrogen()->HasPowerOf2Divisor()) { | 782   if (instr->hydrogen()->HasPowerOf2Divisor()) { | 
| 783     Register dividend = ToRegister(instr->InputAt(0)); | 783     Register dividend = ToRegister(instr->InputAt(0)); | 
| 784 | 784 | 
| 785     int32_t divisor = | 785     int32_t divisor = | 
| 786         HConstant::cast(instr->hydrogen()->right())->Integer32Value(); | 786         HConstant::cast(instr->hydrogen()->right())->Integer32Value(); | 
| 787 | 787 | 
| 788     if (divisor < 0) divisor = -divisor; | 788     if (divisor < 0) divisor = -divisor; | 
| 789 | 789 | 
| 790     NearLabel positive_dividend, done; | 790     Label positive_dividend, done; | 
| 791     __ test(dividend, Operand(dividend)); | 791     __ test(dividend, Operand(dividend)); | 
| 792     __ j(not_sign, &positive_dividend); | 792     __ j(not_sign, &positive_dividend, Label::kNear); | 
| 793     __ neg(dividend); | 793     __ neg(dividend); | 
| 794     __ and_(dividend, divisor - 1); | 794     __ and_(dividend, divisor - 1); | 
| 795     __ neg(dividend); | 795     __ neg(dividend); | 
| 796     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 796     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 797       __ j(not_zero, &done); | 797       __ j(not_zero, &done, Label::kNear); | 
| 798       DeoptimizeIf(no_condition, instr->environment()); | 798       DeoptimizeIf(no_condition, instr->environment()); | 
| 799     } | 799     } | 
| 800     __ bind(&positive_dividend); | 800     __ bind(&positive_dividend); | 
| 801     __ and_(dividend, divisor - 1); | 801     __ and_(dividend, divisor - 1); | 
| 802     __ bind(&done); | 802     __ bind(&done); | 
| 803   } else { | 803   } else { | 
| 804     NearLabel done, remainder_eq_dividend, slow, do_subtraction, both_positive; | 804     Label done, remainder_eq_dividend, slow, do_subtraction, both_positive; | 
| 805     Register left_reg = ToRegister(instr->InputAt(0)); | 805     Register left_reg = ToRegister(instr->InputAt(0)); | 
| 806     Register right_reg = ToRegister(instr->InputAt(1)); | 806     Register right_reg = ToRegister(instr->InputAt(1)); | 
| 807     Register result_reg = ToRegister(instr->result()); | 807     Register result_reg = ToRegister(instr->result()); | 
| 808 | 808 | 
| 809     ASSERT(left_reg.is(eax)); | 809     ASSERT(left_reg.is(eax)); | 
| 810     ASSERT(result_reg.is(edx)); | 810     ASSERT(result_reg.is(edx)); | 
| 811     ASSERT(!right_reg.is(eax)); | 811     ASSERT(!right_reg.is(eax)); | 
| 812     ASSERT(!right_reg.is(edx)); | 812     ASSERT(!right_reg.is(edx)); | 
| 813 | 813 | 
| 814     // Check for x % 0. | 814     // Check for x % 0. | 
| 815     if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 815     if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 
| 816       __ test(right_reg, Operand(right_reg)); | 816       __ test(right_reg, Operand(right_reg)); | 
| 817       DeoptimizeIf(zero, instr->environment()); | 817       DeoptimizeIf(zero, instr->environment()); | 
| 818     } | 818     } | 
| 819 | 819 | 
| 820     __ test(left_reg, Operand(left_reg)); | 820     __ test(left_reg, Operand(left_reg)); | 
| 821     __ j(zero, &remainder_eq_dividend); | 821     __ j(zero, &remainder_eq_dividend, Label::kNear); | 
| 822     __ j(sign, &slow); | 822     __ j(sign, &slow, Label::kNear); | 
| 823 | 823 | 
| 824     __ test(right_reg, Operand(right_reg)); | 824     __ test(right_reg, Operand(right_reg)); | 
| 825     __ j(not_sign, &both_positive); | 825     __ j(not_sign, &both_positive, Label::kNear); | 
| 826     // The sign of the divisor doesn't matter. | 826     // The sign of the divisor doesn't matter. | 
| 827     __ neg(right_reg); | 827     __ neg(right_reg); | 
| 828 | 828 | 
| 829     __ bind(&both_positive); | 829     __ bind(&both_positive); | 
| 830     // If the dividend is smaller than the nonnegative | 830     // If the dividend is smaller than the nonnegative | 
| 831     // divisor, the dividend is the result. | 831     // divisor, the dividend is the result. | 
| 832     __ cmp(left_reg, Operand(right_reg)); | 832     __ cmp(left_reg, Operand(right_reg)); | 
| 833     __ j(less, &remainder_eq_dividend); | 833     __ j(less, &remainder_eq_dividend, Label::kNear); | 
| 834 | 834 | 
| 835     // Check if the divisor is a PowerOfTwo integer. | 835     // Check if the divisor is a PowerOfTwo integer. | 
| 836     Register scratch = ToRegister(instr->TempAt(0)); | 836     Register scratch = ToRegister(instr->TempAt(0)); | 
| 837     __ mov(scratch, right_reg); | 837     __ mov(scratch, right_reg); | 
| 838     __ sub(Operand(scratch), Immediate(1)); | 838     __ sub(Operand(scratch), Immediate(1)); | 
| 839     __ test(scratch, Operand(right_reg)); | 839     __ test(scratch, Operand(right_reg)); | 
| 840     __ j(not_zero, &do_subtraction); | 840     __ j(not_zero, &do_subtraction, Label::kNear); | 
| 841     __ and_(left_reg, Operand(scratch)); | 841     __ and_(left_reg, Operand(scratch)); | 
| 842     __ jmp(&remainder_eq_dividend); | 842     __ jmp(&remainder_eq_dividend, Label::kNear); | 
| 843 | 843 | 
| 844     __ bind(&do_subtraction); | 844     __ bind(&do_subtraction); | 
| 845     const int kUnfolds = 3; | 845     const int kUnfolds = 3; | 
| 846     // Try a few subtractions of the dividend. | 846     // Try a few subtractions of the dividend. | 
| 847     __ mov(scratch, left_reg); | 847     __ mov(scratch, left_reg); | 
| 848     for (int i = 0; i < kUnfolds; i++) { | 848     for (int i = 0; i < kUnfolds; i++) { | 
| 849       // Reduce the dividend by the divisor. | 849       // Reduce the dividend by the divisor. | 
| 850       __ sub(left_reg, Operand(right_reg)); | 850       __ sub(left_reg, Operand(right_reg)); | 
| 851       // Check if the dividend is less than the divisor. | 851       // Check if the dividend is less than the divisor. | 
| 852       __ cmp(left_reg, Operand(right_reg)); | 852       __ cmp(left_reg, Operand(right_reg)); | 
| 853       __ j(less, &remainder_eq_dividend); | 853       __ j(less, &remainder_eq_dividend, Label::kNear); | 
| 854     } | 854     } | 
| 855     __ mov(left_reg, scratch); | 855     __ mov(left_reg, scratch); | 
| 856 | 856 | 
| 857     // Slow case, using idiv instruction. | 857     // Slow case, using idiv instruction. | 
| 858     __ bind(&slow); | 858     __ bind(&slow); | 
| 859     // Sign extend to edx. | 859     // Sign extend to edx. | 
| 860     __ cdq(); | 860     __ cdq(); | 
| 861 | 861 | 
| 862     // Check for (0 % -x) that will produce negative zero. | 862     // Check for (0 % -x) that will produce negative zero. | 
| 863     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 863     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 864       NearLabel positive_left; | 864       Label positive_left; | 
| 865       NearLabel done; | 865       Label done; | 
| 866       __ test(left_reg, Operand(left_reg)); | 866       __ test(left_reg, Operand(left_reg)); | 
| 867       __ j(not_sign, &positive_left); | 867       __ j(not_sign, &positive_left, Label::kNear); | 
| 868       __ idiv(right_reg); | 868       __ idiv(right_reg); | 
| 869 | 869 | 
| 870       // Test the remainder for 0, because then the result would be -0. | 870       // Test the remainder for 0, because then the result would be -0. | 
| 871       __ test(result_reg, Operand(result_reg)); | 871       __ test(result_reg, Operand(result_reg)); | 
| 872       __ j(not_zero, &done); | 872       __ j(not_zero, &done, Label::kNear); | 
| 873 | 873 | 
| 874       DeoptimizeIf(no_condition, instr->environment()); | 874       DeoptimizeIf(no_condition, instr->environment()); | 
| 875       __ bind(&positive_left); | 875       __ bind(&positive_left); | 
| 876       __ idiv(right_reg); | 876       __ idiv(right_reg); | 
| 877       __ bind(&done); | 877       __ bind(&done); | 
| 878     } else { | 878     } else { | 
| 879       __ idiv(right_reg); | 879       __ idiv(right_reg); | 
| 880     } | 880     } | 
| 881     __ jmp(&done); | 881     __ jmp(&done, Label::kNear); | 
| 882 | 882 | 
| 883     __ bind(&remainder_eq_dividend); | 883     __ bind(&remainder_eq_dividend); | 
| 884     __ mov(result_reg, left_reg); | 884     __ mov(result_reg, left_reg); | 
| 885 | 885 | 
| 886     __ bind(&done); | 886     __ bind(&done); | 
| 887   } | 887   } | 
| 888 } | 888 } | 
| 889 | 889 | 
| 890 | 890 | 
| 891 void LCodeGen::DoDivI(LDivI* instr) { | 891 void LCodeGen::DoDivI(LDivI* instr) { | 
| 892   LOperand* right = instr->InputAt(1); | 892   LOperand* right = instr->InputAt(1); | 
| 893   ASSERT(ToRegister(instr->result()).is(eax)); | 893   ASSERT(ToRegister(instr->result()).is(eax)); | 
| 894   ASSERT(ToRegister(instr->InputAt(0)).is(eax)); | 894   ASSERT(ToRegister(instr->InputAt(0)).is(eax)); | 
| 895   ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); | 895   ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); | 
| 896   ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); | 896   ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); | 
| 897 | 897 | 
| 898   Register left_reg = eax; | 898   Register left_reg = eax; | 
| 899 | 899 | 
| 900   // Check for x / 0. | 900   // Check for x / 0. | 
| 901   Register right_reg = ToRegister(right); | 901   Register right_reg = ToRegister(right); | 
| 902   if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 902   if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 
| 903     __ test(right_reg, ToOperand(right)); | 903     __ test(right_reg, ToOperand(right)); | 
| 904     DeoptimizeIf(zero, instr->environment()); | 904     DeoptimizeIf(zero, instr->environment()); | 
| 905   } | 905   } | 
| 906 | 906 | 
| 907   // Check for (0 / -x) that will produce negative zero. | 907   // Check for (0 / -x) that will produce negative zero. | 
| 908   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 908   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 909     NearLabel left_not_zero; | 909     Label left_not_zero; | 
| 910     __ test(left_reg, Operand(left_reg)); | 910     __ test(left_reg, Operand(left_reg)); | 
| 911     __ j(not_zero, &left_not_zero); | 911     __ j(not_zero, &left_not_zero, Label::kNear); | 
| 912     __ test(right_reg, ToOperand(right)); | 912     __ test(right_reg, ToOperand(right)); | 
| 913     DeoptimizeIf(sign, instr->environment()); | 913     DeoptimizeIf(sign, instr->environment()); | 
| 914     __ bind(&left_not_zero); | 914     __ bind(&left_not_zero); | 
| 915   } | 915   } | 
| 916 | 916 | 
| 917   // Check for (-kMinInt / -1). | 917   // Check for (-kMinInt / -1). | 
| 918   if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 918   if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 
| 919     NearLabel left_not_min_int; | 919     Label left_not_min_int; | 
| 920     __ cmp(left_reg, kMinInt); | 920     __ cmp(left_reg, kMinInt); | 
| 921     __ j(not_zero, &left_not_min_int); | 921     __ j(not_zero, &left_not_min_int, Label::kNear); | 
| 922     __ cmp(right_reg, -1); | 922     __ cmp(right_reg, -1); | 
| 923     DeoptimizeIf(zero, instr->environment()); | 923     DeoptimizeIf(zero, instr->environment()); | 
| 924     __ bind(&left_not_min_int); | 924     __ bind(&left_not_min_int); | 
| 925   } | 925   } | 
| 926 | 926 | 
| 927   // Sign extend to edx. | 927   // Sign extend to edx. | 
| 928   __ cdq(); | 928   __ cdq(); | 
| 929   __ idiv(right_reg); | 929   __ idiv(right_reg); | 
| 930 | 930 | 
| 931   // Deoptimize if remainder is not 0. | 931   // Deoptimize if remainder is not 0. | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 989   } else { | 989   } else { | 
| 990     __ imul(left, ToOperand(right)); | 990     __ imul(left, ToOperand(right)); | 
| 991   } | 991   } | 
| 992 | 992 | 
| 993   if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 993   if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 
| 994     DeoptimizeIf(overflow, instr->environment()); | 994     DeoptimizeIf(overflow, instr->environment()); | 
| 995   } | 995   } | 
| 996 | 996 | 
| 997   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 997   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 998     // Bail out if the result is supposed to be negative zero. | 998     // Bail out if the result is supposed to be negative zero. | 
| 999     NearLabel done; | 999     Label done; | 
| 1000     __ test(left, Operand(left)); | 1000     __ test(left, Operand(left)); | 
| 1001     __ j(not_zero, &done); | 1001     __ j(not_zero, &done, Label::kNear); | 
| 1002     if (right->IsConstantOperand()) { | 1002     if (right->IsConstantOperand()) { | 
| 1003       if (ToInteger32(LConstantOperand::cast(right)) <= 0) { | 1003       if (ToInteger32(LConstantOperand::cast(right)) <= 0) { | 
| 1004         DeoptimizeIf(no_condition, instr->environment()); | 1004         DeoptimizeIf(no_condition, instr->environment()); | 
| 1005       } | 1005       } | 
| 1006     } else { | 1006     } else { | 
| 1007       // Test the non-zero operand for negative sign. | 1007       // Test the non-zero operand for negative sign. | 
| 1008       __ or_(ToRegister(instr->TempAt(0)), ToOperand(right)); | 1008       __ or_(ToRegister(instr->TempAt(0)), ToOperand(right)); | 
| 1009       DeoptimizeIf(sign, instr->environment()); | 1009       DeoptimizeIf(sign, instr->environment()); | 
| 1010     } | 1010     } | 
| 1011     __ bind(&done); | 1011     __ bind(&done); | 
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1196   Register array = ToRegister(instr->InputAt(0)); | 1196   Register array = ToRegister(instr->InputAt(0)); | 
| 1197   __ mov(result, FieldOperand(array, ExternalArray::kLengthOffset)); | 1197   __ mov(result, FieldOperand(array, ExternalArray::kLengthOffset)); | 
| 1198 } | 1198 } | 
| 1199 | 1199 | 
| 1200 | 1200 | 
| 1201 void LCodeGen::DoValueOf(LValueOf* instr) { | 1201 void LCodeGen::DoValueOf(LValueOf* instr) { | 
| 1202   Register input = ToRegister(instr->InputAt(0)); | 1202   Register input = ToRegister(instr->InputAt(0)); | 
| 1203   Register result = ToRegister(instr->result()); | 1203   Register result = ToRegister(instr->result()); | 
| 1204   Register map = ToRegister(instr->TempAt(0)); | 1204   Register map = ToRegister(instr->TempAt(0)); | 
| 1205   ASSERT(input.is(result)); | 1205   ASSERT(input.is(result)); | 
| 1206   NearLabel done; | 1206   Label done; | 
| 1207   // If the object is a smi return the object. | 1207   // If the object is a smi return the object. | 
| 1208   __ test(input, Immediate(kSmiTagMask)); | 1208   __ test(input, Immediate(kSmiTagMask)); | 
| 1209   __ j(zero, &done); | 1209   __ j(zero, &done, Label::kNear); | 
| 1210 | 1210 | 
| 1211   // If the object is not a value type, return the object. | 1211   // If the object is not a value type, return the object. | 
| 1212   __ CmpObjectType(input, JS_VALUE_TYPE, map); | 1212   __ CmpObjectType(input, JS_VALUE_TYPE, map); | 
| 1213   __ j(not_equal, &done); | 1213   __ j(not_equal, &done, Label::kNear); | 
| 1214   __ mov(result, FieldOperand(input, JSValue::kValueOffset)); | 1214   __ mov(result, FieldOperand(input, JSValue::kValueOffset)); | 
| 1215 | 1215 | 
| 1216   __ bind(&done); | 1216   __ bind(&done); | 
| 1217 } | 1217 } | 
| 1218 | 1218 | 
| 1219 | 1219 | 
| 1220 void LCodeGen::DoBitNotI(LBitNotI* instr) { | 1220 void LCodeGen::DoBitNotI(LBitNotI* instr) { | 
| 1221   LOperand* input = instr->InputAt(0); | 1221   LOperand* input = instr->InputAt(0); | 
| 1222   ASSERT(input->Equals(instr->result())); | 1222   ASSERT(input->Equals(instr->result())); | 
| 1223   __ not_(ToRegister(input)); | 1223   __ not_(ToRegister(input)); | 
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1361       __ cmp(reg, factory()->true_value()); | 1361       __ cmp(reg, factory()->true_value()); | 
| 1362       __ j(equal, true_label); | 1362       __ j(equal, true_label); | 
| 1363       __ cmp(reg, factory()->false_value()); | 1363       __ cmp(reg, factory()->false_value()); | 
| 1364       __ j(equal, false_label); | 1364       __ j(equal, false_label); | 
| 1365       __ test(reg, Operand(reg)); | 1365       __ test(reg, Operand(reg)); | 
| 1366       __ j(equal, false_label); | 1366       __ j(equal, false_label); | 
| 1367       __ test(reg, Immediate(kSmiTagMask)); | 1367       __ test(reg, Immediate(kSmiTagMask)); | 
| 1368       __ j(zero, true_label); | 1368       __ j(zero, true_label); | 
| 1369 | 1369 | 
| 1370       // Test for double values. Zero is false. | 1370       // Test for double values. Zero is false. | 
| 1371       NearLabel call_stub; | 1371       Label call_stub; | 
| 1372       __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1372       __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 
| 1373              factory()->heap_number_map()); | 1373              factory()->heap_number_map()); | 
| 1374       __ j(not_equal, &call_stub); | 1374       __ j(not_equal, &call_stub, Label::kNear); | 
| 1375       __ fldz(); | 1375       __ fldz(); | 
| 1376       __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 1376       __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 
| 1377       __ FCmp(); | 1377       __ FCmp(); | 
| 1378       __ j(zero, false_label); | 1378       __ j(zero, false_label); | 
| 1379       __ jmp(true_label); | 1379       __ jmp(true_label); | 
| 1380 | 1380 | 
| 1381       // The conversion stub doesn't cause garbage collections so it's | 1381       // The conversion stub doesn't cause garbage collections so it's | 
| 1382       // safe to not record a safepoint after the call. | 1382       // safe to not record a safepoint after the call. | 
| 1383       __ bind(&call_stub); | 1383       __ bind(&call_stub); | 
| 1384       ToBooleanStub stub; | 1384       ToBooleanStub stub; | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1470     __ cmp(ToRegister(left), ToOperand(right)); | 1470     __ cmp(ToRegister(left), ToOperand(right)); | 
| 1471   } | 1471   } | 
| 1472 } | 1472 } | 
| 1473 | 1473 | 
| 1474 | 1474 | 
| 1475 void LCodeGen::DoCmpID(LCmpID* instr) { | 1475 void LCodeGen::DoCmpID(LCmpID* instr) { | 
| 1476   LOperand* left = instr->InputAt(0); | 1476   LOperand* left = instr->InputAt(0); | 
| 1477   LOperand* right = instr->InputAt(1); | 1477   LOperand* right = instr->InputAt(1); | 
| 1478   LOperand* result = instr->result(); | 1478   LOperand* result = instr->result(); | 
| 1479 | 1479 | 
| 1480   NearLabel unordered; | 1480   Label unordered; | 
| 1481   if (instr->is_double()) { | 1481   if (instr->is_double()) { | 
| 1482     // Don't base result on EFLAGS when a NaN is involved. Instead | 1482     // Don't base result on EFLAGS when a NaN is involved. Instead | 
| 1483     // jump to the unordered case, which produces a false value. | 1483     // jump to the unordered case, which produces a false value. | 
| 1484     __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); | 1484     __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); | 
| 1485     __ j(parity_even, &unordered, not_taken); | 1485     __ j(parity_even, &unordered, not_taken, Label::kNear); | 
| 1486   } else { | 1486   } else { | 
| 1487     EmitCmpI(left, right); | 1487     EmitCmpI(left, right); | 
| 1488   } | 1488   } | 
| 1489 | 1489 | 
| 1490   NearLabel done; | 1490   Label done; | 
| 1491   Condition cc = TokenToCondition(instr->op(), instr->is_double()); | 1491   Condition cc = TokenToCondition(instr->op(), instr->is_double()); | 
| 1492   __ mov(ToRegister(result), factory()->true_value()); | 1492   __ mov(ToRegister(result), factory()->true_value()); | 
| 1493   __ j(cc, &done); | 1493   __ j(cc, &done, Label::kNear); | 
| 1494 | 1494 | 
| 1495   __ bind(&unordered); | 1495   __ bind(&unordered); | 
| 1496   __ mov(ToRegister(result), factory()->false_value()); | 1496   __ mov(ToRegister(result), factory()->false_value()); | 
| 1497   __ bind(&done); | 1497   __ bind(&done); | 
| 1498 } | 1498 } | 
| 1499 | 1499 | 
| 1500 | 1500 | 
| 1501 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 1501 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 
| 1502   LOperand* left = instr->InputAt(0); | 1502   LOperand* left = instr->InputAt(0); | 
| 1503   LOperand* right = instr->InputAt(1); | 1503   LOperand* right = instr->InputAt(1); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 1518 } | 1518 } | 
| 1519 | 1519 | 
| 1520 | 1520 | 
| 1521 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { | 1521 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { | 
| 1522   Register left = ToRegister(instr->InputAt(0)); | 1522   Register left = ToRegister(instr->InputAt(0)); | 
| 1523   Register right = ToRegister(instr->InputAt(1)); | 1523   Register right = ToRegister(instr->InputAt(1)); | 
| 1524   Register result = ToRegister(instr->result()); | 1524   Register result = ToRegister(instr->result()); | 
| 1525 | 1525 | 
| 1526   __ cmp(left, Operand(right)); | 1526   __ cmp(left, Operand(right)); | 
| 1527   __ mov(result, factory()->true_value()); | 1527   __ mov(result, factory()->true_value()); | 
| 1528   NearLabel done; | 1528   Label done; | 
| 1529   __ j(equal, &done); | 1529   __ j(equal, &done, Label::kNear); | 
| 1530   __ mov(result, factory()->false_value()); | 1530   __ mov(result, factory()->false_value()); | 
| 1531   __ bind(&done); | 1531   __ bind(&done); | 
| 1532 } | 1532 } | 
| 1533 | 1533 | 
| 1534 | 1534 | 
| 1535 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { | 1535 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { | 
| 1536   Register left = ToRegister(instr->InputAt(0)); | 1536   Register left = ToRegister(instr->InputAt(0)); | 
| 1537   Register right = ToRegister(instr->InputAt(1)); | 1537   Register right = ToRegister(instr->InputAt(1)); | 
| 1538   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1538   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 
| 1539   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1539   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 
| 1540 | 1540 | 
| 1541   __ cmp(left, Operand(right)); | 1541   __ cmp(left, Operand(right)); | 
| 1542   EmitBranch(true_block, false_block, equal); | 1542   EmitBranch(true_block, false_block, equal); | 
| 1543 } | 1543 } | 
| 1544 | 1544 | 
| 1545 | 1545 | 
| 1546 void LCodeGen::DoIsNull(LIsNull* instr) { | 1546 void LCodeGen::DoIsNull(LIsNull* instr) { | 
| 1547   Register reg = ToRegister(instr->InputAt(0)); | 1547   Register reg = ToRegister(instr->InputAt(0)); | 
| 1548   Register result = ToRegister(instr->result()); | 1548   Register result = ToRegister(instr->result()); | 
| 1549 | 1549 | 
| 1550   // TODO(fsc): If the expression is known to be a smi, then it's | 1550   // TODO(fsc): If the expression is known to be a smi, then it's | 
| 1551   // definitely not null. Materialize false. | 1551   // definitely not null. Materialize false. | 
| 1552 | 1552 | 
| 1553   __ cmp(reg, factory()->null_value()); | 1553   __ cmp(reg, factory()->null_value()); | 
| 1554   if (instr->is_strict()) { | 1554   if (instr->is_strict()) { | 
| 1555     __ mov(result, factory()->true_value()); | 1555     __ mov(result, factory()->true_value()); | 
| 1556     NearLabel done; | 1556     Label done; | 
| 1557     __ j(equal, &done); | 1557     __ j(equal, &done, Label::kNear); | 
| 1558     __ mov(result, factory()->false_value()); | 1558     __ mov(result, factory()->false_value()); | 
| 1559     __ bind(&done); | 1559     __ bind(&done); | 
| 1560   } else { | 1560   } else { | 
| 1561     NearLabel true_value, false_value, done; | 1561     Label true_value, false_value, done; | 
| 1562     __ j(equal, &true_value); | 1562     __ j(equal, &true_value, Label::kNear); | 
| 1563     __ cmp(reg, factory()->undefined_value()); | 1563     __ cmp(reg, factory()->undefined_value()); | 
| 1564     __ j(equal, &true_value); | 1564     __ j(equal, &true_value, Label::kNear); | 
| 1565     __ test(reg, Immediate(kSmiTagMask)); | 1565     __ test(reg, Immediate(kSmiTagMask)); | 
| 1566     __ j(zero, &false_value); | 1566     __ j(zero, &false_value, Label::kNear); | 
| 1567     // Check for undetectable objects by looking in the bit field in | 1567     // Check for undetectable objects by looking in the bit field in | 
| 1568     // the map. The object has already been smi checked. | 1568     // the map. The object has already been smi checked. | 
| 1569     Register scratch = result; | 1569     Register scratch = result; | 
| 1570     __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 1570     __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 
| 1571     __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); | 1571     __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); | 
| 1572     __ test(scratch, Immediate(1 << Map::kIsUndetectable)); | 1572     __ test(scratch, Immediate(1 << Map::kIsUndetectable)); | 
| 1573     __ j(not_zero, &true_value); | 1573     __ j(not_zero, &true_value, Label::kNear); | 
| 1574     __ bind(&false_value); | 1574     __ bind(&false_value); | 
| 1575     __ mov(result, factory()->false_value()); | 1575     __ mov(result, factory()->false_value()); | 
| 1576     __ jmp(&done); | 1576     __ jmp(&done, Label::kNear); | 
| 1577     __ bind(&true_value); | 1577     __ bind(&true_value); | 
| 1578     __ mov(result, factory()->true_value()); | 1578     __ mov(result, factory()->true_value()); | 
| 1579     __ bind(&done); | 1579     __ bind(&done); | 
| 1580   } | 1580   } | 
| 1581 } | 1581 } | 
| 1582 | 1582 | 
| 1583 | 1583 | 
| 1584 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { | 1584 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { | 
| 1585   Register reg = ToRegister(instr->InputAt(0)); | 1585   Register reg = ToRegister(instr->InputAt(0)); | 
| 1586 | 1586 | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1677 } | 1677 } | 
| 1678 | 1678 | 
| 1679 | 1679 | 
| 1680 void LCodeGen::DoIsSmi(LIsSmi* instr) { | 1680 void LCodeGen::DoIsSmi(LIsSmi* instr) { | 
| 1681   Operand input = ToOperand(instr->InputAt(0)); | 1681   Operand input = ToOperand(instr->InputAt(0)); | 
| 1682   Register result = ToRegister(instr->result()); | 1682   Register result = ToRegister(instr->result()); | 
| 1683 | 1683 | 
| 1684   ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1684   ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 
| 1685   __ test(input, Immediate(kSmiTagMask)); | 1685   __ test(input, Immediate(kSmiTagMask)); | 
| 1686   __ mov(result, factory()->true_value()); | 1686   __ mov(result, factory()->true_value()); | 
| 1687   NearLabel done; | 1687   Label done; | 
| 1688   __ j(zero, &done); | 1688   __ j(zero, &done, Label::kNear); | 
| 1689   __ mov(result, factory()->false_value()); | 1689   __ mov(result, factory()->false_value()); | 
| 1690   __ bind(&done); | 1690   __ bind(&done); | 
| 1691 } | 1691 } | 
| 1692 | 1692 | 
| 1693 | 1693 | 
| 1694 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 1694 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 
| 1695   Operand input = ToOperand(instr->InputAt(0)); | 1695   Operand input = ToOperand(instr->InputAt(0)); | 
| 1696 | 1696 | 
| 1697   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1697   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 
| 1698   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1698   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 1721   return equal; | 1721   return equal; | 
| 1722 } | 1722 } | 
| 1723 | 1723 | 
| 1724 | 1724 | 
| 1725 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { | 1725 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { | 
| 1726   Register input = ToRegister(instr->InputAt(0)); | 1726   Register input = ToRegister(instr->InputAt(0)); | 
| 1727   Register result = ToRegister(instr->result()); | 1727   Register result = ToRegister(instr->result()); | 
| 1728 | 1728 | 
| 1729   ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1729   ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 
| 1730   __ test(input, Immediate(kSmiTagMask)); | 1730   __ test(input, Immediate(kSmiTagMask)); | 
| 1731   NearLabel done, is_false; | 1731   Label done, is_false; | 
| 1732   __ j(zero, &is_false); | 1732   __ j(zero, &is_false, Label::kNear); | 
| 1733   __ CmpObjectType(input, TestType(instr->hydrogen()), result); | 1733   __ CmpObjectType(input, TestType(instr->hydrogen()), result); | 
| 1734   __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); | 1734   __ j(NegateCondition(BranchCondition(instr->hydrogen())), | 
|  | 1735        &is_false, Label::kNear); | 
| 1735   __ mov(result, factory()->true_value()); | 1736   __ mov(result, factory()->true_value()); | 
| 1736   __ jmp(&done); | 1737   __ jmp(&done, Label::kNear); | 
| 1737   __ bind(&is_false); | 1738   __ bind(&is_false); | 
| 1738   __ mov(result, factory()->false_value()); | 1739   __ mov(result, factory()->false_value()); | 
| 1739   __ bind(&done); | 1740   __ bind(&done); | 
| 1740 } | 1741 } | 
| 1741 | 1742 | 
| 1742 | 1743 | 
| 1743 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 1744 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 
| 1744   Register input = ToRegister(instr->InputAt(0)); | 1745   Register input = ToRegister(instr->InputAt(0)); | 
| 1745   Register temp = ToRegister(instr->TempAt(0)); | 1746   Register temp = ToRegister(instr->TempAt(0)); | 
| 1746 | 1747 | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 1771 | 1772 | 
| 1772 | 1773 | 
| 1773 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { | 1774 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { | 
| 1774   Register input = ToRegister(instr->InputAt(0)); | 1775   Register input = ToRegister(instr->InputAt(0)); | 
| 1775   Register result = ToRegister(instr->result()); | 1776   Register result = ToRegister(instr->result()); | 
| 1776 | 1777 | 
| 1777   ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1778   ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 
| 1778   __ mov(result, factory()->true_value()); | 1779   __ mov(result, factory()->true_value()); | 
| 1779   __ test(FieldOperand(input, String::kHashFieldOffset), | 1780   __ test(FieldOperand(input, String::kHashFieldOffset), | 
| 1780           Immediate(String::kContainsCachedArrayIndexMask)); | 1781           Immediate(String::kContainsCachedArrayIndexMask)); | 
| 1781   NearLabel done; | 1782   Label done; | 
| 1782   __ j(zero, &done); | 1783   __ j(zero, &done, Label::kNear); | 
| 1783   __ mov(result, factory()->false_value()); | 1784   __ mov(result, factory()->false_value()); | 
| 1784   __ bind(&done); | 1785   __ bind(&done); | 
| 1785 } | 1786 } | 
| 1786 | 1787 | 
| 1787 | 1788 | 
| 1788 void LCodeGen::DoHasCachedArrayIndexAndBranch( | 1789 void LCodeGen::DoHasCachedArrayIndexAndBranch( | 
| 1789     LHasCachedArrayIndexAndBranch* instr) { | 1790     LHasCachedArrayIndexAndBranch* instr) { | 
| 1790   Register input = ToRegister(instr->InputAt(0)); | 1791   Register input = ToRegister(instr->InputAt(0)); | 
| 1791 | 1792 | 
| 1792   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1793   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1854   // End with the answer in the z flag. | 1855   // End with the answer in the z flag. | 
| 1855 } | 1856 } | 
| 1856 | 1857 | 
| 1857 | 1858 | 
| 1858 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { | 1859 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { | 
| 1859   Register input = ToRegister(instr->InputAt(0)); | 1860   Register input = ToRegister(instr->InputAt(0)); | 
| 1860   Register result = ToRegister(instr->result()); | 1861   Register result = ToRegister(instr->result()); | 
| 1861   ASSERT(input.is(result)); | 1862   ASSERT(input.is(result)); | 
| 1862   Register temp = ToRegister(instr->TempAt(0)); | 1863   Register temp = ToRegister(instr->TempAt(0)); | 
| 1863   Handle<String> class_name = instr->hydrogen()->class_name(); | 1864   Handle<String> class_name = instr->hydrogen()->class_name(); | 
| 1864   NearLabel done; | 1865   Label done; | 
| 1865   Label is_true, is_false; | 1866   Label is_true, is_false; | 
| 1866 | 1867 | 
| 1867   EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); | 1868   EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); | 
| 1868 | 1869 | 
| 1869   __ j(not_equal, &is_false); | 1870   __ j(not_equal, &is_false, Label::kNear); | 
| 1870 | 1871 | 
| 1871   __ bind(&is_true); | 1872   __ bind(&is_true); | 
| 1872   __ mov(result, factory()->true_value()); | 1873   __ mov(result, factory()->true_value()); | 
| 1873   __ jmp(&done); | 1874   __ jmp(&done, Label::kNear); | 
| 1874 | 1875 | 
| 1875   __ bind(&is_false); | 1876   __ bind(&is_false); | 
| 1876   __ mov(result, factory()->false_value()); | 1877   __ mov(result, factory()->false_value()); | 
| 1877   __ bind(&done); | 1878   __ bind(&done); | 
| 1878 } | 1879 } | 
| 1879 | 1880 | 
| 1880 | 1881 | 
| 1881 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { | 1882 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { | 
| 1882   Register input = ToRegister(instr->InputAt(0)); | 1883   Register input = ToRegister(instr->InputAt(0)); | 
| 1883   Register temp = ToRegister(instr->TempAt(0)); | 1884   Register temp = ToRegister(instr->TempAt(0)); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 1911   EmitBranch(true_block, false_block, equal); | 1912   EmitBranch(true_block, false_block, equal); | 
| 1912 } | 1913 } | 
| 1913 | 1914 | 
| 1914 | 1915 | 
| 1915 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 1916 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 
| 1916   // Object and function are in fixed registers defined by the stub. | 1917   // Object and function are in fixed registers defined by the stub. | 
| 1917   ASSERT(ToRegister(instr->context()).is(esi)); | 1918   ASSERT(ToRegister(instr->context()).is(esi)); | 
| 1918   InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 1919   InstanceofStub stub(InstanceofStub::kArgsInRegisters); | 
| 1919   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 1920   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| 1920 | 1921 | 
| 1921   NearLabel true_value, done; | 1922   Label true_value, done; | 
| 1922   __ test(eax, Operand(eax)); | 1923   __ test(eax, Operand(eax)); | 
| 1923   __ j(zero, &true_value); | 1924   __ j(zero, &true_value, Label::kNear); | 
| 1924   __ mov(ToRegister(instr->result()), factory()->false_value()); | 1925   __ mov(ToRegister(instr->result()), factory()->false_value()); | 
| 1925   __ jmp(&done); | 1926   __ jmp(&done, Label::kNear); | 
| 1926   __ bind(&true_value); | 1927   __ bind(&true_value); | 
| 1927   __ mov(ToRegister(instr->result()), factory()->true_value()); | 1928   __ mov(ToRegister(instr->result()), factory()->true_value()); | 
| 1928   __ bind(&done); | 1929   __ bind(&done); | 
| 1929 } | 1930 } | 
| 1930 | 1931 | 
| 1931 | 1932 | 
| 1932 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { | 1933 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { | 
| 1933   ASSERT(ToRegister(instr->context()).is(esi)); | 1934   ASSERT(ToRegister(instr->context()).is(esi)); | 
| 1934   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1935   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 
| 1935   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1936   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 1965   Register object = ToRegister(instr->InputAt(0)); | 1966   Register object = ToRegister(instr->InputAt(0)); | 
| 1966   Register temp = ToRegister(instr->TempAt(0)); | 1967   Register temp = ToRegister(instr->TempAt(0)); | 
| 1967 | 1968 | 
| 1968   // A Smi is not an instance of anything. | 1969   // A Smi is not an instance of anything. | 
| 1969   __ test(object, Immediate(kSmiTagMask)); | 1970   __ test(object, Immediate(kSmiTagMask)); | 
| 1970   __ j(zero, &false_result, not_taken); | 1971   __ j(zero, &false_result, not_taken); | 
| 1971 | 1972 | 
| 1972   // This is the inlined call site instanceof cache. The two occurences of the | 1973   // This is the inlined call site instanceof cache. The two occurences of the | 
| 1973   // hole value will be patched to the last map/result pair generated by the | 1974   // hole value will be patched to the last map/result pair generated by the | 
| 1974   // instanceof stub. | 1975   // instanceof stub. | 
| 1975   NearLabel cache_miss; | 1976   Label cache_miss; | 
| 1976   Register map = ToRegister(instr->TempAt(0)); | 1977   Register map = ToRegister(instr->TempAt(0)); | 
| 1977   __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); | 1978   __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); | 
| 1978   __ bind(deferred->map_check());  // Label for calculating code patching. | 1979   __ bind(deferred->map_check());  // Label for calculating code patching. | 
| 1979   __ cmp(map, factory()->the_hole_value());  // Patched to cached map. | 1980   __ cmp(map, factory()->the_hole_value());  // Patched to cached map. | 
| 1980   __ j(not_equal, &cache_miss, not_taken); | 1981   __ j(not_equal, &cache_miss, not_taken, Label::kNear); | 
| 1981   __ mov(eax, factory()->the_hole_value());  // Patched to either true or false. | 1982   __ mov(eax, factory()->the_hole_value());  // Patched to either true or false. | 
| 1982   __ jmp(&done); | 1983   __ jmp(&done); | 
| 1983 | 1984 | 
| 1984   // The inlined call site cache did not match. Check for null and string | 1985   // The inlined call site cache did not match. Check for null and string | 
| 1985   // before calling the deferred code. | 1986   // before calling the deferred code. | 
| 1986   __ bind(&cache_miss); | 1987   __ bind(&cache_miss); | 
| 1987   // Null is not an instance of anything. | 1988   // Null is not an instance of anything. | 
| 1988   __ cmp(object, factory()->null_value()); | 1989   __ cmp(object, factory()->null_value()); | 
| 1989   __ j(equal, &false_result); | 1990   __ j(equal, &false_result); | 
| 1990 | 1991 | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2062 void LCodeGen::DoCmpT(LCmpT* instr) { | 2063 void LCodeGen::DoCmpT(LCmpT* instr) { | 
| 2063   Token::Value op = instr->op(); | 2064   Token::Value op = instr->op(); | 
| 2064 | 2065 | 
| 2065   Handle<Code> ic = CompareIC::GetUninitialized(op); | 2066   Handle<Code> ic = CompareIC::GetUninitialized(op); | 
| 2066   CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 2067   CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| 2067 | 2068 | 
| 2068   Condition condition = ComputeCompareCondition(op); | 2069   Condition condition = ComputeCompareCondition(op); | 
| 2069   if (op == Token::GT || op == Token::LTE) { | 2070   if (op == Token::GT || op == Token::LTE) { | 
| 2070     condition = ReverseCondition(condition); | 2071     condition = ReverseCondition(condition); | 
| 2071   } | 2072   } | 
| 2072   NearLabel true_value, done; | 2073   Label true_value, done; | 
| 2073   __ test(eax, Operand(eax)); | 2074   __ test(eax, Operand(eax)); | 
| 2074   __ j(condition, &true_value); | 2075   __ j(condition, &true_value, Label::kNear); | 
| 2075   __ mov(ToRegister(instr->result()), factory()->false_value()); | 2076   __ mov(ToRegister(instr->result()), factory()->false_value()); | 
| 2076   __ jmp(&done); | 2077   __ jmp(&done, Label::kNear); | 
| 2077   __ bind(&true_value); | 2078   __ bind(&true_value); | 
| 2078   __ mov(ToRegister(instr->result()), factory()->true_value()); | 2079   __ mov(ToRegister(instr->result()), factory()->true_value()); | 
| 2079   __ bind(&done); | 2080   __ bind(&done); | 
| 2080 } | 2081 } | 
| 2081 | 2082 | 
| 2082 | 2083 | 
| 2083 void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) { | 2084 void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) { | 
| 2084   Token::Value op = instr->op(); | 2085   Token::Value op = instr->op(); | 
| 2085   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2086   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 
| 2086   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2087   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2232   Register result = ToRegister(instr->result()); | 2233   Register result = ToRegister(instr->result()); | 
| 2233 | 2234 | 
| 2234   int map_count = instr->hydrogen()->types()->length(); | 2235   int map_count = instr->hydrogen()->types()->length(); | 
| 2235   Handle<String> name = instr->hydrogen()->name(); | 2236   Handle<String> name = instr->hydrogen()->name(); | 
| 2236   if (map_count == 0) { | 2237   if (map_count == 0) { | 
| 2237     ASSERT(instr->hydrogen()->need_generic()); | 2238     ASSERT(instr->hydrogen()->need_generic()); | 
| 2238     __ mov(ecx, name); | 2239     __ mov(ecx, name); | 
| 2239     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2240     Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 
| 2240     CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 2241     CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| 2241   } else { | 2242   } else { | 
| 2242     NearLabel done; | 2243     Label done; | 
| 2243     for (int i = 0; i < map_count - 1; ++i) { | 2244     for (int i = 0; i < map_count - 1; ++i) { | 
| 2244       Handle<Map> map = instr->hydrogen()->types()->at(i); | 2245       Handle<Map> map = instr->hydrogen()->types()->at(i); | 
| 2245       NearLabel next; | 2246       Label next; | 
| 2246       __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); | 2247       __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); | 
| 2247       __ j(not_equal, &next); | 2248       __ j(not_equal, &next, Label::kNear); | 
| 2248       EmitLoadFieldOrConstantFunction(result, object, map, name); | 2249       EmitLoadFieldOrConstantFunction(result, object, map, name); | 
| 2249       __ jmp(&done); | 2250       __ jmp(&done, Label::kNear); | 
| 2250       __ bind(&next); | 2251       __ bind(&next); | 
| 2251     } | 2252     } | 
| 2252     Handle<Map> map = instr->hydrogen()->types()->last(); | 2253     Handle<Map> map = instr->hydrogen()->types()->last(); | 
| 2253     __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); | 2254     __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); | 
| 2254     if (instr->hydrogen()->need_generic()) { | 2255     if (instr->hydrogen()->need_generic()) { | 
| 2255       NearLabel generic; | 2256       Label generic; | 
| 2256       __ j(not_equal, &generic); | 2257       __ j(not_equal, &generic, Label::kNear); | 
| 2257       EmitLoadFieldOrConstantFunction(result, object, map, name); | 2258       EmitLoadFieldOrConstantFunction(result, object, map, name); | 
| 2258       __ jmp(&done); | 2259       __ jmp(&done, Label::kNear); | 
| 2259       __ bind(&generic); | 2260       __ bind(&generic); | 
| 2260       __ mov(ecx, name); | 2261       __ mov(ecx, name); | 
| 2261       Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2262       Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 
| 2262       CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 2263       CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| 2263     } else { | 2264     } else { | 
| 2264       DeoptimizeIf(not_equal, instr->environment()); | 2265       DeoptimizeIf(not_equal, instr->environment()); | 
| 2265       EmitLoadFieldOrConstantFunction(result, object, map, name); | 2266       EmitLoadFieldOrConstantFunction(result, object, map, name); | 
| 2266     } | 2267     } | 
| 2267     __ bind(&done); | 2268     __ bind(&done); | 
| 2268   } | 2269   } | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 2283 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 2284 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 
| 2284   Register function = ToRegister(instr->function()); | 2285   Register function = ToRegister(instr->function()); | 
| 2285   Register temp = ToRegister(instr->TempAt(0)); | 2286   Register temp = ToRegister(instr->TempAt(0)); | 
| 2286   Register result = ToRegister(instr->result()); | 2287   Register result = ToRegister(instr->result()); | 
| 2287 | 2288 | 
| 2288   // Check that the function really is a function. | 2289   // Check that the function really is a function. | 
| 2289   __ CmpObjectType(function, JS_FUNCTION_TYPE, result); | 2290   __ CmpObjectType(function, JS_FUNCTION_TYPE, result); | 
| 2290   DeoptimizeIf(not_equal, instr->environment()); | 2291   DeoptimizeIf(not_equal, instr->environment()); | 
| 2291 | 2292 | 
| 2292   // Check whether the function has an instance prototype. | 2293   // Check whether the function has an instance prototype. | 
| 2293   NearLabel non_instance; | 2294   Label non_instance; | 
| 2294   __ test_b(FieldOperand(result, Map::kBitFieldOffset), | 2295   __ test_b(FieldOperand(result, Map::kBitFieldOffset), | 
| 2295             1 << Map::kHasNonInstancePrototype); | 2296             1 << Map::kHasNonInstancePrototype); | 
| 2296   __ j(not_zero, &non_instance); | 2297   __ j(not_zero, &non_instance, Label::kNear); | 
| 2297 | 2298 | 
| 2298   // Get the prototype or initial map from the function. | 2299   // Get the prototype or initial map from the function. | 
| 2299   __ mov(result, | 2300   __ mov(result, | 
| 2300          FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 2301          FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); | 
| 2301 | 2302 | 
| 2302   // Check that the function has a prototype or an initial map. | 2303   // Check that the function has a prototype or an initial map. | 
| 2303   __ cmp(Operand(result), Immediate(factory()->the_hole_value())); | 2304   __ cmp(Operand(result), Immediate(factory()->the_hole_value())); | 
| 2304   DeoptimizeIf(equal, instr->environment()); | 2305   DeoptimizeIf(equal, instr->environment()); | 
| 2305 | 2306 | 
| 2306   // If the function does not have an initial map, we're done. | 2307   // If the function does not have an initial map, we're done. | 
| 2307   NearLabel done; | 2308   Label done; | 
| 2308   __ CmpObjectType(result, MAP_TYPE, temp); | 2309   __ CmpObjectType(result, MAP_TYPE, temp); | 
| 2309   __ j(not_equal, &done); | 2310   __ j(not_equal, &done, Label::kNear); | 
| 2310 | 2311 | 
| 2311   // Get the prototype from the initial map. | 2312   // Get the prototype from the initial map. | 
| 2312   __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); | 2313   __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); | 
| 2313   __ jmp(&done); | 2314   __ jmp(&done, Label::kNear); | 
| 2314 | 2315 | 
| 2315   // Non-instance prototype: Fetch prototype from constructor field | 2316   // Non-instance prototype: Fetch prototype from constructor field | 
| 2316   // in the function's map. | 2317   // in the function's map. | 
| 2317   __ bind(&non_instance); | 2318   __ bind(&non_instance); | 
| 2318   __ mov(result, FieldOperand(result, Map::kConstructorOffset)); | 2319   __ mov(result, FieldOperand(result, Map::kConstructorOffset)); | 
| 2319 | 2320 | 
| 2320   // All done. | 2321   // All done. | 
| 2321   __ bind(&done); | 2322   __ bind(&done); | 
| 2322 } | 2323 } | 
| 2323 | 2324 | 
| 2324 | 2325 | 
| 2325 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 2326 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 
| 2326   Register result = ToRegister(instr->result()); | 2327   Register result = ToRegister(instr->result()); | 
| 2327   Register input = ToRegister(instr->InputAt(0)); | 2328   Register input = ToRegister(instr->InputAt(0)); | 
| 2328   __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); | 2329   __ mov(result, FieldOperand(input, JSObject::kElementsOffset)); | 
| 2329   if (FLAG_debug_code) { | 2330   if (FLAG_debug_code) { | 
| 2330     NearLabel done; | 2331     Label done; | 
| 2331     __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2332     __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 
| 2332            Immediate(factory()->fixed_array_map())); | 2333            Immediate(factory()->fixed_array_map())); | 
| 2333     __ j(equal, &done); | 2334     __ j(equal, &done, Label::kNear); | 
| 2334     __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 2335     __ cmp(FieldOperand(result, HeapObject::kMapOffset), | 
| 2335            Immediate(factory()->fixed_cow_array_map())); | 2336            Immediate(factory()->fixed_cow_array_map())); | 
| 2336     __ j(equal, &done); | 2337     __ j(equal, &done, Label::kNear); | 
| 2337     Register temp((result.is(eax)) ? ebx : eax); | 2338     Register temp((result.is(eax)) ? ebx : eax); | 
| 2338     __ push(temp); | 2339     __ push(temp); | 
| 2339     __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); | 2340     __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); | 
| 2340     __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); | 2341     __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); | 
| 2341     __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE)); | 2342     __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE)); | 
| 2342     __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount)); | 2343     __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount)); | 
| 2343     __ pop(temp); | 2344     __ pop(temp); | 
| 2344     __ Check(below, "Check for fast elements or pixel array failed."); | 2345     __ Check(below, "Check for fast elements or pixel array failed."); | 
| 2345     __ bind(&done); | 2346     __ bind(&done); | 
| 2346   } | 2347   } | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2444 | 2445 | 
| 2445   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2446   Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 
| 2446   CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 2447   CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); | 
| 2447 } | 2448 } | 
| 2448 | 2449 | 
| 2449 | 2450 | 
| 2450 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 2451 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { | 
| 2451   Register result = ToRegister(instr->result()); | 2452   Register result = ToRegister(instr->result()); | 
| 2452 | 2453 | 
| 2453   // Check for arguments adapter frame. | 2454   // Check for arguments adapter frame. | 
| 2454   NearLabel done, adapted; | 2455   Label done, adapted; | 
| 2455   __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 2456   __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 
| 2456   __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); | 2457   __ mov(result, Operand(result, StandardFrameConstants::kContextOffset)); | 
| 2457   __ cmp(Operand(result), | 2458   __ cmp(Operand(result), | 
| 2458          Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2459          Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 
| 2459   __ j(equal, &adapted); | 2460   __ j(equal, &adapted, Label::kNear); | 
| 2460 | 2461 | 
| 2461   // No arguments adaptor frame. | 2462   // No arguments adaptor frame. | 
| 2462   __ mov(result, Operand(ebp)); | 2463   __ mov(result, Operand(ebp)); | 
| 2463   __ jmp(&done); | 2464   __ jmp(&done, Label::kNear); | 
| 2464 | 2465 | 
| 2465   // Arguments adaptor frame present. | 2466   // Arguments adaptor frame present. | 
| 2466   __ bind(&adapted); | 2467   __ bind(&adapted); | 
| 2467   __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 2468   __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 
| 2468 | 2469 | 
| 2469   // Result is the frame pointer for the frame if not adapted and for the real | 2470   // Result is the frame pointer for the frame if not adapted and for the real | 
| 2470   // frame below the adaptor frame if adapted. | 2471   // frame below the adaptor frame if adapted. | 
| 2471   __ bind(&done); | 2472   __ bind(&done); | 
| 2472 } | 2473 } | 
| 2473 | 2474 | 
| 2474 | 2475 | 
| 2475 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { | 2476 void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { | 
| 2476   Operand elem = ToOperand(instr->InputAt(0)); | 2477   Operand elem = ToOperand(instr->InputAt(0)); | 
| 2477   Register result = ToRegister(instr->result()); | 2478   Register result = ToRegister(instr->result()); | 
| 2478 | 2479 | 
| 2479   NearLabel done; | 2480   Label done; | 
| 2480 | 2481 | 
| 2481   // If no arguments adaptor frame the number of arguments is fixed. | 2482   // If no arguments adaptor frame the number of arguments is fixed. | 
| 2482   __ cmp(ebp, elem); | 2483   __ cmp(ebp, elem); | 
| 2483   __ mov(result, Immediate(scope()->num_parameters())); | 2484   __ mov(result, Immediate(scope()->num_parameters())); | 
| 2484   __ j(equal, &done); | 2485   __ j(equal, &done, Label::kNear); | 
| 2485 | 2486 | 
| 2486   // Arguments adaptor frame present. Get argument length from there. | 2487   // Arguments adaptor frame present. Get argument length from there. | 
| 2487   __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 2488   __ mov(result, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 
| 2488   __ mov(result, Operand(result, | 2489   __ mov(result, Operand(result, | 
| 2489                          ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2490                          ArgumentsAdaptorFrameConstants::kLengthOffset)); | 
| 2490   __ SmiUntag(result); | 2491   __ SmiUntag(result); | 
| 2491 | 2492 | 
| 2492   // Argument length is in result register. | 2493   // Argument length is in result register. | 
| 2493   __ bind(&done); | 2494   __ bind(&done); | 
| 2494 } | 2495 } | 
| 2495 | 2496 | 
| 2496 | 2497 | 
| 2497 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 2498 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 
| 2498   Register receiver = ToRegister(instr->receiver()); | 2499   Register receiver = ToRegister(instr->receiver()); | 
| 2499   Register function = ToRegister(instr->function()); | 2500   Register function = ToRegister(instr->function()); | 
| 2500   Register length = ToRegister(instr->length()); | 2501   Register length = ToRegister(instr->length()); | 
| 2501   Register elements = ToRegister(instr->elements()); | 2502   Register elements = ToRegister(instr->elements()); | 
| 2502   Register scratch = ToRegister(instr->TempAt(0)); | 2503   Register scratch = ToRegister(instr->TempAt(0)); | 
| 2503   ASSERT(receiver.is(eax));  // Used for parameter count. | 2504   ASSERT(receiver.is(eax));  // Used for parameter count. | 
| 2504   ASSERT(function.is(edi));  // Required by InvokeFunction. | 2505   ASSERT(function.is(edi));  // Required by InvokeFunction. | 
| 2505   ASSERT(ToRegister(instr->result()).is(eax)); | 2506   ASSERT(ToRegister(instr->result()).is(eax)); | 
| 2506 | 2507 | 
| 2507   // If the receiver is null or undefined, we have to pass the global object | 2508   // If the receiver is null or undefined, we have to pass the global object | 
| 2508   // as a receiver. | 2509   // as a receiver. | 
| 2509   NearLabel global_object, receiver_ok; | 2510   Label global_object, receiver_ok; | 
| 2510   __ cmp(receiver, factory()->null_value()); | 2511   __ cmp(receiver, factory()->null_value()); | 
| 2511   __ j(equal, &global_object); | 2512   __ j(equal, &global_object, Label::kNear); | 
| 2512   __ cmp(receiver, factory()->undefined_value()); | 2513   __ cmp(receiver, factory()->undefined_value()); | 
| 2513   __ j(equal, &global_object); | 2514   __ j(equal, &global_object, Label::kNear); | 
| 2514 | 2515 | 
| 2515   // The receiver should be a JS object. | 2516   // The receiver should be a JS object. | 
| 2516   __ test(receiver, Immediate(kSmiTagMask)); | 2517   __ test(receiver, Immediate(kSmiTagMask)); | 
| 2517   DeoptimizeIf(equal, instr->environment()); | 2518   DeoptimizeIf(equal, instr->environment()); | 
| 2518   __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch); | 2519   __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch); | 
| 2519   DeoptimizeIf(below, instr->environment()); | 2520   DeoptimizeIf(below, instr->environment()); | 
| 2520   __ jmp(&receiver_ok); | 2521   __ jmp(&receiver_ok, Label::kNear); | 
| 2521 | 2522 | 
| 2522   __ bind(&global_object); | 2523   __ bind(&global_object); | 
| 2523   // TODO(kmillikin): We have a hydrogen value for the global object.  See | 2524   // TODO(kmillikin): We have a hydrogen value for the global object.  See | 
| 2524   // if it's better to use it than to explicitly fetch it from the context | 2525   // if it's better to use it than to explicitly fetch it from the context | 
| 2525   // here. | 2526   // here. | 
| 2526   __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2527   __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| 2527   __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX)); | 2528   __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX)); | 
| 2528   __ bind(&receiver_ok); | 2529   __ bind(&receiver_ok); | 
| 2529 | 2530 | 
| 2530   // Copy the arguments to this function possibly from the | 2531   // Copy the arguments to this function possibly from the | 
| 2531   // adaptor frame below it. | 2532   // adaptor frame below it. | 
| 2532   const uint32_t kArgumentsLimit = 1 * KB; | 2533   const uint32_t kArgumentsLimit = 1 * KB; | 
| 2533   __ cmp(length, kArgumentsLimit); | 2534   __ cmp(length, kArgumentsLimit); | 
| 2534   DeoptimizeIf(above, instr->environment()); | 2535   DeoptimizeIf(above, instr->environment()); | 
| 2535 | 2536 | 
| 2536   __ push(receiver); | 2537   __ push(receiver); | 
| 2537   __ mov(receiver, length); | 2538   __ mov(receiver, length); | 
| 2538 | 2539 | 
| 2539   // Loop through the arguments pushing them onto the execution | 2540   // Loop through the arguments pushing them onto the execution | 
| 2540   // stack. | 2541   // stack. | 
| 2541   NearLabel invoke, loop; | 2542   Label invoke, loop; | 
| 2542   // length is a small non-negative integer, due to the test above. | 2543   // length is a small non-negative integer, due to the test above. | 
| 2543   __ test(length, Operand(length)); | 2544   __ test(length, Operand(length)); | 
| 2544   __ j(zero, &invoke); | 2545   __ j(zero, &invoke, Label::kNear); | 
| 2545   __ bind(&loop); | 2546   __ bind(&loop); | 
| 2546   __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); | 2547   __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); | 
| 2547   __ dec(length); | 2548   __ dec(length); | 
| 2548   __ j(not_zero, &loop); | 2549   __ j(not_zero, &loop); | 
| 2549 | 2550 | 
| 2550   // Invoke the function. | 2551   // Invoke the function. | 
| 2551   __ bind(&invoke); | 2552   __ bind(&invoke); | 
| 2552   ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 2553   ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); | 
| 2553   LPointerMap* pointers = instr->pointer_map(); | 2554   LPointerMap* pointers = instr->pointer_map(); | 
| 2554   LEnvironment* env = instr->deoptimization_environment(); | 2555   LEnvironment* env = instr->deoptimization_environment(); | 
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2886   __ sub(Operand(esp), Immediate(kDoubleSize)); | 2887   __ sub(Operand(esp), Immediate(kDoubleSize)); | 
| 2887   __ fstp_d(Operand(esp, 0)); | 2888   __ fstp_d(Operand(esp, 0)); | 
| 2888   __ movdbl(result_reg, Operand(esp, 0)); | 2889   __ movdbl(result_reg, Operand(esp, 0)); | 
| 2889   __ add(Operand(esp), Immediate(kDoubleSize)); | 2890   __ add(Operand(esp), Immediate(kDoubleSize)); | 
| 2890 } | 2891 } | 
| 2891 | 2892 | 
| 2892 | 2893 | 
| 2893 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 2894 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { | 
| 2894   ASSERT(instr->InputAt(0)->Equals(instr->result())); | 2895   ASSERT(instr->InputAt(0)->Equals(instr->result())); | 
| 2895   XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 2896   XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 
| 2896   NearLabel positive, done, zero, negative; | 2897   Label positive, done, zero; | 
| 2897   __ xorps(xmm0, xmm0); | 2898   __ xorps(xmm0, xmm0); | 
| 2898   __ ucomisd(input_reg, xmm0); | 2899   __ ucomisd(input_reg, xmm0); | 
| 2899   __ j(above, &positive); | 2900   __ j(above, &positive, Label::kNear); | 
| 2900   __ j(equal, &zero); | 2901   __ j(equal, &zero, Label::kNear); | 
| 2901   ExternalReference nan = ExternalReference::address_of_nan(); | 2902   ExternalReference nan = ExternalReference::address_of_nan(); | 
| 2902   __ movdbl(input_reg, Operand::StaticVariable(nan)); | 2903   __ movdbl(input_reg, Operand::StaticVariable(nan)); | 
| 2903   __ jmp(&done); | 2904   __ jmp(&done, Label::kNear); | 
| 2904   __ bind(&zero); | 2905   __ bind(&zero); | 
| 2905   __ push(Immediate(0xFFF00000)); | 2906   __ push(Immediate(0xFFF00000)); | 
| 2906   __ push(Immediate(0)); | 2907   __ push(Immediate(0)); | 
| 2907   __ movdbl(input_reg, Operand(esp, 0)); | 2908   __ movdbl(input_reg, Operand(esp, 0)); | 
| 2908   __ add(Operand(esp), Immediate(kDoubleSize)); | 2909   __ add(Operand(esp), Immediate(kDoubleSize)); | 
| 2909   __ jmp(&done); | 2910   __ jmp(&done, Label::kNear); | 
| 2910   __ bind(&positive); | 2911   __ bind(&positive); | 
| 2911   __ fldln2(); | 2912   __ fldln2(); | 
| 2912   __ sub(Operand(esp), Immediate(kDoubleSize)); | 2913   __ sub(Operand(esp), Immediate(kDoubleSize)); | 
| 2913   __ movdbl(Operand(esp, 0), input_reg); | 2914   __ movdbl(Operand(esp, 0), input_reg); | 
| 2914   __ fld_d(Operand(esp, 0)); | 2915   __ fld_d(Operand(esp, 0)); | 
| 2915   __ fyl2x(); | 2916   __ fyl2x(); | 
| 2916   __ fstp_d(Operand(esp, 0)); | 2917   __ fstp_d(Operand(esp, 0)); | 
| 2917   __ movdbl(input_reg, Operand(esp, 0)); | 2918   __ movdbl(input_reg, Operand(esp, 0)); | 
| 2918   __ add(Operand(esp), Immediate(kDoubleSize)); | 2919   __ add(Operand(esp), Immediate(kDoubleSize)); | 
| 2919   __ bind(&done); | 2920   __ bind(&done); | 
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3119     switch (array_type) { | 3120     switch (array_type) { | 
| 3120       case kExternalPixelArray: { | 3121       case kExternalPixelArray: { | 
| 3121         // Clamp the value to [0..255]. | 3122         // Clamp the value to [0..255]. | 
| 3122         Register temp = ToRegister(instr->TempAt(0)); | 3123         Register temp = ToRegister(instr->TempAt(0)); | 
| 3123         // The dec_b below requires that the clamped value is in a byte | 3124         // The dec_b below requires that the clamped value is in a byte | 
| 3124         // register. eax is an arbitrary choice to satisfy this requirement, we | 3125         // register. eax is an arbitrary choice to satisfy this requirement, we | 
| 3125         // hinted the register allocator to give us eax when building the | 3126         // hinted the register allocator to give us eax when building the | 
| 3126         // instruction. | 3127         // instruction. | 
| 3127         ASSERT(temp.is(eax)); | 3128         ASSERT(temp.is(eax)); | 
| 3128         __ mov(temp, ToRegister(instr->value())); | 3129         __ mov(temp, ToRegister(instr->value())); | 
| 3129         NearLabel done; | 3130         Label done; | 
| 3130         __ test(temp, Immediate(0xFFFFFF00)); | 3131         __ test(temp, Immediate(0xFFFFFF00)); | 
| 3131         __ j(zero, &done); | 3132         __ j(zero, &done, Label::kNear); | 
| 3132         __ setcc(negative, temp);  // 1 if negative, 0 if positive. | 3133         __ setcc(negative, temp);  // 1 if negative, 0 if positive. | 
| 3133         __ dec_b(temp);  // 0 if negative, 255 if positive. | 3134         __ dec_b(temp);  // 0 if negative, 255 if positive. | 
| 3134         __ bind(&done); | 3135         __ bind(&done); | 
| 3135         __ mov_b(Operand(external_pointer, key, times_1, 0), temp); | 3136         __ mov_b(Operand(external_pointer, key, times_1, 0), temp); | 
| 3136         break; | 3137         break; | 
| 3137       } | 3138       } | 
| 3138       case kExternalByteArray: | 3139       case kExternalByteArray: | 
| 3139       case kExternalUnsignedByteArray: | 3140       case kExternalUnsignedByteArray: | 
| 3140         __ mov_b(Operand(external_pointer, key, times_1, 0), value); | 3141         __ mov_b(Operand(external_pointer, key, times_1, 0), value); | 
| 3141         break; | 3142         break; | 
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3228       return; | 3229       return; | 
| 3229     } | 3230     } | 
| 3230   } else { | 3231   } else { | 
| 3231     index = ToRegister(instr->index()); | 3232     index = ToRegister(instr->index()); | 
| 3232   } | 3233   } | 
| 3233   Register result = ToRegister(instr->result()); | 3234   Register result = ToRegister(instr->result()); | 
| 3234 | 3235 | 
| 3235   DeferredStringCharCodeAt* deferred = | 3236   DeferredStringCharCodeAt* deferred = | 
| 3236       new DeferredStringCharCodeAt(this, instr); | 3237       new DeferredStringCharCodeAt(this, instr); | 
| 3237 | 3238 | 
| 3238   NearLabel flat_string, ascii_string, done; | 3239   Label flat_string, ascii_string, done; | 
| 3239 | 3240 | 
| 3240   // Fetch the instance type of the receiver into result register. | 3241   // Fetch the instance type of the receiver into result register. | 
| 3241   __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); | 3242   __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); | 
| 3242   __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 3243   __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 
| 3243 | 3244 | 
| 3244   // We need special handling for non-flat strings. | 3245   // We need special handling for non-flat strings. | 
| 3245   STATIC_ASSERT(kSeqStringTag == 0); | 3246   STATIC_ASSERT(kSeqStringTag == 0); | 
| 3246   __ test(result, Immediate(kStringRepresentationMask)); | 3247   __ test(result, Immediate(kStringRepresentationMask)); | 
| 3247   __ j(zero, &flat_string); | 3248   __ j(zero, &flat_string, Label::kNear); | 
| 3248 | 3249 | 
| 3249   // Handle non-flat strings. | 3250   // Handle non-flat strings. | 
| 3250   __ test(result, Immediate(kIsConsStringMask)); | 3251   __ test(result, Immediate(kIsConsStringMask)); | 
| 3251   __ j(zero, deferred->entry()); | 3252   __ j(zero, deferred->entry()); | 
| 3252 | 3253 | 
| 3253   // ConsString. | 3254   // ConsString. | 
| 3254   // Check whether the right hand side is the empty string (i.e. if | 3255   // Check whether the right hand side is the empty string (i.e. if | 
| 3255   // this is really a flat string in a cons string). If that is not | 3256   // this is really a flat string in a cons string). If that is not | 
| 3256   // the case we would rather go to the runtime system now to flatten | 3257   // the case we would rather go to the runtime system now to flatten | 
| 3257   // the string. | 3258   // the string. | 
| 3258   __ cmp(FieldOperand(string, ConsString::kSecondOffset), | 3259   __ cmp(FieldOperand(string, ConsString::kSecondOffset), | 
| 3259          Immediate(factory()->empty_string())); | 3260          Immediate(factory()->empty_string())); | 
| 3260   __ j(not_equal, deferred->entry()); | 3261   __ j(not_equal, deferred->entry()); | 
| 3261   // Get the first of the two strings and load its instance type. | 3262   // Get the first of the two strings and load its instance type. | 
| 3262   __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); | 3263   __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); | 
| 3263   __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); | 3264   __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); | 
| 3264   __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 3265   __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); | 
| 3265   // If the first cons component is also non-flat, then go to runtime. | 3266   // If the first cons component is also non-flat, then go to runtime. | 
| 3266   STATIC_ASSERT(kSeqStringTag == 0); | 3267   STATIC_ASSERT(kSeqStringTag == 0); | 
| 3267   __ test(result, Immediate(kStringRepresentationMask)); | 3268   __ test(result, Immediate(kStringRepresentationMask)); | 
| 3268   __ j(not_zero, deferred->entry()); | 3269   __ j(not_zero, deferred->entry()); | 
| 3269 | 3270 | 
| 3270   // Check for ASCII or two-byte string. | 3271   // Check for ASCII or two-byte string. | 
| 3271   __ bind(&flat_string); | 3272   __ bind(&flat_string); | 
| 3272   STATIC_ASSERT(kAsciiStringTag != 0); | 3273   STATIC_ASSERT(kAsciiStringTag != 0); | 
| 3273   __ test(result, Immediate(kStringEncodingMask)); | 3274   __ test(result, Immediate(kStringEncodingMask)); | 
| 3274   __ j(not_zero, &ascii_string); | 3275   __ j(not_zero, &ascii_string, Label::kNear); | 
| 3275 | 3276 | 
| 3276   // Two-byte string. | 3277   // Two-byte string. | 
| 3277   // Load the two-byte character code into the result register. | 3278   // Load the two-byte character code into the result register. | 
| 3278   STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 3279   STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 
| 3279   if (instr->index()->IsConstantOperand()) { | 3280   if (instr->index()->IsConstantOperand()) { | 
| 3280     __ movzx_w(result, | 3281     __ movzx_w(result, | 
| 3281                FieldOperand(string, | 3282                FieldOperand(string, | 
| 3282                             SeqTwoByteString::kHeaderSize + | 3283                             SeqTwoByteString::kHeaderSize + | 
| 3283                             (kUC16Size * const_index))); | 3284                             (kUC16Size * const_index))); | 
| 3284   } else { | 3285   } else { | 
| 3285     __ movzx_w(result, FieldOperand(string, | 3286     __ movzx_w(result, FieldOperand(string, | 
| 3286                                     index, | 3287                                     index, | 
| 3287                                     times_2, | 3288                                     times_2, | 
| 3288                                     SeqTwoByteString::kHeaderSize)); | 3289                                     SeqTwoByteString::kHeaderSize)); | 
| 3289   } | 3290   } | 
| 3290   __ jmp(&done); | 3291   __ jmp(&done, Label::kNear); | 
| 3291 | 3292 | 
| 3292   // ASCII string. | 3293   // ASCII string. | 
| 3293   // Load the byte into the result register. | 3294   // Load the byte into the result register. | 
| 3294   __ bind(&ascii_string); | 3295   __ bind(&ascii_string); | 
| 3295   if (instr->index()->IsConstantOperand()) { | 3296   if (instr->index()->IsConstantOperand()) { | 
| 3296     __ movzx_b(result, FieldOperand(string, | 3297     __ movzx_b(result, FieldOperand(string, | 
| 3297                                     SeqAsciiString::kHeaderSize + const_index)); | 3298                                     SeqAsciiString::kHeaderSize + const_index)); | 
| 3298   } else { | 3299   } else { | 
| 3299     __ movzx_b(result, FieldOperand(string, | 3300     __ movzx_b(result, FieldOperand(string, | 
| 3300                                     index, | 3301                                     index, | 
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3441   Label slow; | 3442   Label slow; | 
| 3442   Register reg = ToRegister(instr->InputAt(0)); | 3443   Register reg = ToRegister(instr->InputAt(0)); | 
| 3443   Register tmp = reg.is(eax) ? ecx : eax; | 3444   Register tmp = reg.is(eax) ? ecx : eax; | 
| 3444 | 3445 | 
| 3445   // Preserve the value of all registers. | 3446   // Preserve the value of all registers. | 
| 3446   PushSafepointRegistersScope scope(this); | 3447   PushSafepointRegistersScope scope(this); | 
| 3447 | 3448 | 
| 3448   // There was overflow, so bits 30 and 31 of the original integer | 3449   // There was overflow, so bits 30 and 31 of the original integer | 
| 3449   // disagree. Try to allocate a heap number in new space and store | 3450   // disagree. Try to allocate a heap number in new space and store | 
| 3450   // the value in there. If that fails, call the runtime system. | 3451   // the value in there. If that fails, call the runtime system. | 
| 3451   NearLabel done; | 3452   Label done; | 
| 3452   __ SmiUntag(reg); | 3453   __ SmiUntag(reg); | 
| 3453   __ xor_(reg, 0x80000000); | 3454   __ xor_(reg, 0x80000000); | 
| 3454   __ cvtsi2sd(xmm0, Operand(reg)); | 3455   __ cvtsi2sd(xmm0, Operand(reg)); | 
| 3455   if (FLAG_inline_new) { | 3456   if (FLAG_inline_new) { | 
| 3456     __ AllocateHeapNumber(reg, tmp, no_reg, &slow); | 3457     __ AllocateHeapNumber(reg, tmp, no_reg, &slow); | 
| 3457     __ jmp(&done); | 3458     __ jmp(&done, Label::kNear); | 
| 3458   } | 3459   } | 
| 3459 | 3460 | 
| 3460   // Slow case: Call the runtime system to do the number allocation. | 3461   // Slow case: Call the runtime system to do the number allocation. | 
| 3461   __ bind(&slow); | 3462   __ bind(&slow); | 
| 3462 | 3463 | 
| 3463   // TODO(3095996): Put a valid pointer value in the stack slot where the result | 3464   // TODO(3095996): Put a valid pointer value in the stack slot where the result | 
| 3464   // register is stored, as this register is in the pointer map, but contains an | 3465   // register is stored, as this register is in the pointer map, but contains an | 
| 3465   // integer value. | 3466   // integer value. | 
| 3466   __ StoreToSafepointRegisterSlot(reg, Immediate(0)); | 3467   __ StoreToSafepointRegisterSlot(reg, Immediate(0)); | 
| 3467 | 3468 | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3529     __ test(ToRegister(input), Immediate(kSmiTagMask)); | 3530     __ test(ToRegister(input), Immediate(kSmiTagMask)); | 
| 3530     DeoptimizeIf(not_zero, instr->environment()); | 3531     DeoptimizeIf(not_zero, instr->environment()); | 
| 3531   } | 3532   } | 
| 3532   __ SmiUntag(ToRegister(input)); | 3533   __ SmiUntag(ToRegister(input)); | 
| 3533 } | 3534 } | 
| 3534 | 3535 | 
| 3535 | 3536 | 
| 3536 void LCodeGen::EmitNumberUntagD(Register input_reg, | 3537 void LCodeGen::EmitNumberUntagD(Register input_reg, | 
| 3537                                 XMMRegister result_reg, | 3538                                 XMMRegister result_reg, | 
| 3538                                 LEnvironment* env) { | 3539                                 LEnvironment* env) { | 
| 3539   NearLabel load_smi, heap_number, done; | 3540   Label load_smi, heap_number, done; | 
| 3540 | 3541 | 
| 3541   // Smi check. | 3542   // Smi check. | 
| 3542   __ test(input_reg, Immediate(kSmiTagMask)); | 3543   __ test(input_reg, Immediate(kSmiTagMask)); | 
| 3543   __ j(zero, &load_smi, not_taken); | 3544   __ j(zero, &load_smi, not_taken, Label::kNear); | 
| 3544 | 3545 | 
| 3545   // Heap number map check. | 3546   // Heap number map check. | 
| 3546   __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3547   __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 
| 3547          factory()->heap_number_map()); | 3548          factory()->heap_number_map()); | 
| 3548   __ j(equal, &heap_number); | 3549   __ j(equal, &heap_number, Label::kNear); | 
| 3549 | 3550 | 
| 3550   __ cmp(input_reg, factory()->undefined_value()); | 3551   __ cmp(input_reg, factory()->undefined_value()); | 
| 3551   DeoptimizeIf(not_equal, env); | 3552   DeoptimizeIf(not_equal, env); | 
| 3552 | 3553 | 
| 3553   // Convert undefined to NaN. | 3554   // Convert undefined to NaN. | 
| 3554   ExternalReference nan = ExternalReference::address_of_nan(); | 3555   ExternalReference nan = ExternalReference::address_of_nan(); | 
| 3555   __ movdbl(result_reg, Operand::StaticVariable(nan)); | 3556   __ movdbl(result_reg, Operand::StaticVariable(nan)); | 
| 3556   __ jmp(&done); | 3557   __ jmp(&done, Label::kNear); | 
| 3557 | 3558 | 
| 3558   // Heap number to XMM conversion. | 3559   // Heap number to XMM conversion. | 
| 3559   __ bind(&heap_number); | 3560   __ bind(&heap_number); | 
| 3560   __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3561   __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 
| 3561   __ jmp(&done); | 3562   __ jmp(&done, Label::kNear); | 
| 3562 | 3563 | 
| 3563   // Smi to XMM conversion | 3564   // Smi to XMM conversion | 
| 3564   __ bind(&load_smi); | 3565   __ bind(&load_smi); | 
| 3565   __ SmiUntag(input_reg);  // Untag smi before converting to float. | 3566   __ SmiUntag(input_reg);  // Untag smi before converting to float. | 
| 3566   __ cvtsi2sd(result_reg, Operand(input_reg)); | 3567   __ cvtsi2sd(result_reg, Operand(input_reg)); | 
| 3567   __ SmiTag(input_reg);  // Retag smi. | 3568   __ SmiTag(input_reg);  // Retag smi. | 
| 3568   __ bind(&done); | 3569   __ bind(&done); | 
| 3569 } | 3570 } | 
| 3570 | 3571 | 
| 3571 | 3572 | 
| 3572 class DeferredTaggedToI: public LDeferredCode { | 3573 class DeferredTaggedToI: public LDeferredCode { | 
| 3573  public: | 3574  public: | 
| 3574   DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 3575   DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 
| 3575       : LDeferredCode(codegen), instr_(instr) { } | 3576       : LDeferredCode(codegen), instr_(instr) { } | 
| 3576   virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } | 3577   virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); } | 
| 3577  private: | 3578  private: | 
| 3578   LTaggedToI* instr_; | 3579   LTaggedToI* instr_; | 
| 3579 }; | 3580 }; | 
| 3580 | 3581 | 
| 3581 | 3582 | 
| 3582 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 3583 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { | 
| 3583   NearLabel done, heap_number; | 3584   Label done, heap_number; | 
| 3584   Register input_reg = ToRegister(instr->InputAt(0)); | 3585   Register input_reg = ToRegister(instr->InputAt(0)); | 
| 3585 | 3586 | 
| 3586   // Heap number map check. | 3587   // Heap number map check. | 
| 3587   __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3588   __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 
| 3588          factory()->heap_number_map()); | 3589          factory()->heap_number_map()); | 
| 3589 | 3590 | 
| 3590   if (instr->truncating()) { | 3591   if (instr->truncating()) { | 
| 3591     __ j(equal, &heap_number); | 3592     __ j(equal, &heap_number, Label::kNear); | 
| 3592     // Check for undefined. Undefined is converted to zero for truncating | 3593     // Check for undefined. Undefined is converted to zero for truncating | 
| 3593     // conversions. | 3594     // conversions. | 
| 3594     __ cmp(input_reg, factory()->undefined_value()); | 3595     __ cmp(input_reg, factory()->undefined_value()); | 
| 3595     DeoptimizeIf(not_equal, instr->environment()); | 3596     DeoptimizeIf(not_equal, instr->environment()); | 
| 3596     __ mov(input_reg, 0); | 3597     __ mov(input_reg, 0); | 
| 3597     __ jmp(&done); | 3598     __ jmp(&done, Label::kNear); | 
| 3598 | 3599 | 
| 3599     __ bind(&heap_number); | 3600     __ bind(&heap_number); | 
| 3600     if (CpuFeatures::IsSupported(SSE3)) { | 3601     if (CpuFeatures::IsSupported(SSE3)) { | 
| 3601       CpuFeatures::Scope scope(SSE3); | 3602       CpuFeatures::Scope scope(SSE3); | 
| 3602       NearLabel convert; | 3603       Label convert; | 
| 3603       // Use more powerful conversion when sse3 is available. | 3604       // Use more powerful conversion when sse3 is available. | 
| 3604       // Load x87 register with heap number. | 3605       // Load x87 register with heap number. | 
| 3605       __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3606       __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); | 
| 3606       // Get exponent alone and check for too-big exponent. | 3607       // Get exponent alone and check for too-big exponent. | 
| 3607       __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 3608       __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 
| 3608       __ and_(input_reg, HeapNumber::kExponentMask); | 3609       __ and_(input_reg, HeapNumber::kExponentMask); | 
| 3609       const uint32_t kTooBigExponent = | 3610       const uint32_t kTooBigExponent = | 
| 3610           (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | 3611           (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | 
| 3611       __ cmp(Operand(input_reg), Immediate(kTooBigExponent)); | 3612       __ cmp(Operand(input_reg), Immediate(kTooBigExponent)); | 
| 3612       __ j(less, &convert); | 3613       __ j(less, &convert, Label::kNear); | 
| 3613       // Pop FPU stack before deoptimizing. | 3614       // Pop FPU stack before deoptimizing. | 
| 3614       __ ffree(0); | 3615       __ ffree(0); | 
| 3615       __ fincstp(); | 3616       __ fincstp(); | 
| 3616       DeoptimizeIf(no_condition, instr->environment()); | 3617       DeoptimizeIf(no_condition, instr->environment()); | 
| 3617 | 3618 | 
| 3618       // Reserve space for 64 bit answer. | 3619       // Reserve space for 64 bit answer. | 
| 3619       __ bind(&convert); | 3620       __ bind(&convert); | 
| 3620       __ sub(Operand(esp), Immediate(kDoubleSize)); | 3621       __ sub(Operand(esp), Immediate(kDoubleSize)); | 
| 3621       // Do conversion, which cannot fail because we checked the exponent. | 3622       // Do conversion, which cannot fail because we checked the exponent. | 
| 3622       __ fisttp_d(Operand(esp, 0)); | 3623       __ fisttp_d(Operand(esp, 0)); | 
| 3623       __ mov(input_reg, Operand(esp, 0));  // Low word of answer is the result. | 3624       __ mov(input_reg, Operand(esp, 0));  // Low word of answer is the result. | 
| 3624       __ add(Operand(esp), Immediate(kDoubleSize)); | 3625       __ add(Operand(esp), Immediate(kDoubleSize)); | 
| 3625     } else { | 3626     } else { | 
| 3626       NearLabel deopt; |  | 
| 3627       XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); | 3627       XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); | 
| 3628       __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3628       __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 
| 3629       __ cvttsd2si(input_reg, Operand(xmm0)); | 3629       __ cvttsd2si(input_reg, Operand(xmm0)); | 
| 3630       __ cmp(input_reg, 0x80000000u); | 3630       __ cmp(input_reg, 0x80000000u); | 
| 3631       __ j(not_equal, &done); | 3631       __ j(not_equal, &done); | 
| 3632       // Check if the input was 0x8000000 (kMinInt). | 3632       // Check if the input was 0x8000000 (kMinInt). | 
| 3633       // If no, then we got an overflow and we deoptimize. | 3633       // If no, then we got an overflow and we deoptimize. | 
| 3634       ExternalReference min_int = ExternalReference::address_of_min_int(); | 3634       ExternalReference min_int = ExternalReference::address_of_min_int(); | 
| 3635       __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); | 3635       __ movdbl(xmm_temp, Operand::StaticVariable(min_int)); | 
| 3636       __ ucomisd(xmm_temp, xmm0); | 3636       __ ucomisd(xmm_temp, xmm0); | 
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3703   Register result_reg = ToRegister(result); | 3703   Register result_reg = ToRegister(result); | 
| 3704 | 3704 | 
| 3705   if (instr->truncating()) { | 3705   if (instr->truncating()) { | 
| 3706     // Performs a truncating conversion of a floating point number as used by | 3706     // Performs a truncating conversion of a floating point number as used by | 
| 3707     // the JS bitwise operations. | 3707     // the JS bitwise operations. | 
| 3708     __ cvttsd2si(result_reg, Operand(input_reg)); | 3708     __ cvttsd2si(result_reg, Operand(input_reg)); | 
| 3709     __ cmp(result_reg, 0x80000000u); | 3709     __ cmp(result_reg, 0x80000000u); | 
| 3710     if (CpuFeatures::IsSupported(SSE3)) { | 3710     if (CpuFeatures::IsSupported(SSE3)) { | 
| 3711       // This will deoptimize if the exponent of the input in out of range. | 3711       // This will deoptimize if the exponent of the input in out of range. | 
| 3712       CpuFeatures::Scope scope(SSE3); | 3712       CpuFeatures::Scope scope(SSE3); | 
| 3713       NearLabel convert, done; | 3713       Label convert, done; | 
| 3714       __ j(not_equal, &done); | 3714       __ j(not_equal, &done, Label::kNear); | 
| 3715       __ sub(Operand(esp), Immediate(kDoubleSize)); | 3715       __ sub(Operand(esp), Immediate(kDoubleSize)); | 
| 3716       __ movdbl(Operand(esp, 0), input_reg); | 3716       __ movdbl(Operand(esp, 0), input_reg); | 
| 3717       // Get exponent alone and check for too-big exponent. | 3717       // Get exponent alone and check for too-big exponent. | 
| 3718       __ mov(result_reg, Operand(esp, sizeof(int32_t))); | 3718       __ mov(result_reg, Operand(esp, sizeof(int32_t))); | 
| 3719       __ and_(result_reg, HeapNumber::kExponentMask); | 3719       __ and_(result_reg, HeapNumber::kExponentMask); | 
| 3720       const uint32_t kTooBigExponent = | 3720       const uint32_t kTooBigExponent = | 
| 3721           (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | 3721           (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | 
| 3722       __ cmp(Operand(result_reg), Immediate(kTooBigExponent)); | 3722       __ cmp(Operand(result_reg), Immediate(kTooBigExponent)); | 
| 3723       __ j(less, &convert); | 3723       __ j(less, &convert, Label::kNear); | 
| 3724       __ add(Operand(esp), Immediate(kDoubleSize)); | 3724       __ add(Operand(esp), Immediate(kDoubleSize)); | 
| 3725       DeoptimizeIf(no_condition, instr->environment()); | 3725       DeoptimizeIf(no_condition, instr->environment()); | 
| 3726       __ bind(&convert); | 3726       __ bind(&convert); | 
| 3727       // Do conversion, which cannot fail because we checked the exponent. | 3727       // Do conversion, which cannot fail because we checked the exponent. | 
| 3728       __ fld_d(Operand(esp, 0)); | 3728       __ fld_d(Operand(esp, 0)); | 
| 3729       __ fisttp_d(Operand(esp, 0)); | 3729       __ fisttp_d(Operand(esp, 0)); | 
| 3730       __ mov(result_reg, Operand(esp, 0));  // Low word of answer is the result. | 3730       __ mov(result_reg, Operand(esp, 0));  // Low word of answer is the result. | 
| 3731       __ add(Operand(esp), Immediate(kDoubleSize)); | 3731       __ add(Operand(esp), Immediate(kDoubleSize)); | 
| 3732       __ bind(&done); | 3732       __ bind(&done); | 
| 3733     } else { | 3733     } else { | 
| 3734       NearLabel done; | 3734       Label done; | 
| 3735       Register temp_reg = ToRegister(instr->TempAt(0)); | 3735       Register temp_reg = ToRegister(instr->TempAt(0)); | 
| 3736       XMMRegister xmm_scratch = xmm0; | 3736       XMMRegister xmm_scratch = xmm0; | 
| 3737 | 3737 | 
| 3738       // If cvttsd2si succeeded, we're done. Otherwise, we attempt | 3738       // If cvttsd2si succeeded, we're done. Otherwise, we attempt | 
| 3739       // manual conversion. | 3739       // manual conversion. | 
| 3740       __ j(not_equal, &done); | 3740       __ j(not_equal, &done, Label::kNear); | 
| 3741 | 3741 | 
| 3742       // Get high 32 bits of the input in result_reg and temp_reg. | 3742       // Get high 32 bits of the input in result_reg and temp_reg. | 
| 3743       __ pshufd(xmm_scratch, input_reg, 1); | 3743       __ pshufd(xmm_scratch, input_reg, 1); | 
| 3744       __ movd(Operand(temp_reg), xmm_scratch); | 3744       __ movd(Operand(temp_reg), xmm_scratch); | 
| 3745       __ mov(result_reg, temp_reg); | 3745       __ mov(result_reg, temp_reg); | 
| 3746 | 3746 | 
| 3747       // Prepare negation mask in temp_reg. | 3747       // Prepare negation mask in temp_reg. | 
| 3748       __ sar(temp_reg, kBitsPerInt - 1); | 3748       __ sar(temp_reg, kBitsPerInt - 1); | 
| 3749 | 3749 | 
| 3750       // Extract the exponent from result_reg and subtract adjusted | 3750       // Extract the exponent from result_reg and subtract adjusted | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 3780       // Shift the input right and extract low 32 bits. | 3780       // Shift the input right and extract low 32 bits. | 
| 3781       __ psrlq(input_reg, xmm_scratch); | 3781       __ psrlq(input_reg, xmm_scratch); | 
| 3782       __ movd(Operand(result_reg), input_reg); | 3782       __ movd(Operand(result_reg), input_reg); | 
| 3783 | 3783 | 
| 3784       // Use the prepared mask in temp_reg to negate the result if necessary. | 3784       // Use the prepared mask in temp_reg to negate the result if necessary. | 
| 3785       __ xor_(result_reg, Operand(temp_reg)); | 3785       __ xor_(result_reg, Operand(temp_reg)); | 
| 3786       __ sub(result_reg, Operand(temp_reg)); | 3786       __ sub(result_reg, Operand(temp_reg)); | 
| 3787       __ bind(&done); | 3787       __ bind(&done); | 
| 3788     } | 3788     } | 
| 3789   } else { | 3789   } else { | 
| 3790     NearLabel done; | 3790     Label done; | 
| 3791     __ cvttsd2si(result_reg, Operand(input_reg)); | 3791     __ cvttsd2si(result_reg, Operand(input_reg)); | 
| 3792     __ cvtsi2sd(xmm0, Operand(result_reg)); | 3792     __ cvtsi2sd(xmm0, Operand(result_reg)); | 
| 3793     __ ucomisd(xmm0, input_reg); | 3793     __ ucomisd(xmm0, input_reg); | 
| 3794     DeoptimizeIf(not_equal, instr->environment()); | 3794     DeoptimizeIf(not_equal, instr->environment()); | 
| 3795     DeoptimizeIf(parity_even, instr->environment());  // NaN. | 3795     DeoptimizeIf(parity_even, instr->environment());  // NaN. | 
| 3796     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3796     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| 3797       // The integer converted back is equal to the original. We | 3797       // The integer converted back is equal to the original. We | 
| 3798       // only have to test if we got -0 as an input. | 3798       // only have to test if we got -0 as an input. | 
| 3799       __ test(result_reg, Operand(result_reg)); | 3799       __ test(result_reg, Operand(result_reg)); | 
| 3800       __ j(not_zero, &done); | 3800       __ j(not_zero, &done, Label::kNear); | 
| 3801       __ movmskpd(result_reg, input_reg); | 3801       __ movmskpd(result_reg, input_reg); | 
| 3802       // Bit 0 contains the sign of the double in input_reg. | 3802       // Bit 0 contains the sign of the double in input_reg. | 
| 3803       // If input was positive, we are ok and return 0, otherwise | 3803       // If input was positive, we are ok and return 0, otherwise | 
| 3804       // deoptimize. | 3804       // deoptimize. | 
| 3805       __ and_(result_reg, 1); | 3805       __ and_(result_reg, 1); | 
| 3806       DeoptimizeIf(not_zero, instr->environment()); | 3806       DeoptimizeIf(not_zero, instr->environment()); | 
| 3807     } | 3807     } | 
| 3808     __ bind(&done); | 3808     __ bind(&done); | 
| 3809   } | 3809   } | 
| 3810 } | 3810 } | 
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3967 | 3967 | 
| 3968 | 3968 | 
| 3969 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { | 3969 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { | 
| 3970   ASSERT(ToRegister(instr->InputAt(0)).is(eax)); | 3970   ASSERT(ToRegister(instr->InputAt(0)).is(eax)); | 
| 3971   __ push(eax); | 3971   __ push(eax); | 
| 3972   CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED); | 3972   CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED); | 
| 3973 } | 3973 } | 
| 3974 | 3974 | 
| 3975 | 3975 | 
| 3976 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 3976 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 
| 3977   NearLabel materialized; | 3977   Label materialized; | 
| 3978   // Registers will be used as follows: | 3978   // Registers will be used as follows: | 
| 3979   // edi = JS function. | 3979   // edi = JS function. | 
| 3980   // ecx = literals array. | 3980   // ecx = literals array. | 
| 3981   // ebx = regexp literal. | 3981   // ebx = regexp literal. | 
| 3982   // eax = regexp literal clone. | 3982   // eax = regexp literal clone. | 
| 3983   __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3983   __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 
| 3984   __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 3984   __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 
| 3985   int literal_offset = FixedArray::kHeaderSize + | 3985   int literal_offset = FixedArray::kHeaderSize + | 
| 3986       instr->hydrogen()->literal_index() * kPointerSize; | 3986       instr->hydrogen()->literal_index() * kPointerSize; | 
| 3987   __ mov(ebx, FieldOperand(ecx, literal_offset)); | 3987   __ mov(ebx, FieldOperand(ecx, literal_offset)); | 
| 3988   __ cmp(ebx, factory()->undefined_value()); | 3988   __ cmp(ebx, factory()->undefined_value()); | 
| 3989   __ j(not_equal, &materialized); | 3989   __ j(not_equal, &materialized, Label::kNear); | 
| 3990 | 3990 | 
| 3991   // Create regexp literal using runtime function | 3991   // Create regexp literal using runtime function | 
| 3992   // Result will be in eax. | 3992   // Result will be in eax. | 
| 3993   __ push(ecx); | 3993   __ push(ecx); | 
| 3994   __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 3994   __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 
| 3995   __ push(Immediate(instr->hydrogen()->pattern())); | 3995   __ push(Immediate(instr->hydrogen()->pattern())); | 
| 3996   __ push(Immediate(instr->hydrogen()->flags())); | 3996   __ push(Immediate(instr->hydrogen()->flags())); | 
| 3997   CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT); | 3997   CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT); | 
| 3998   __ mov(ebx, eax); | 3998   __ mov(ebx, eax); | 
| 3999 | 3999 | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4055   } | 4055   } | 
| 4056   CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); | 4056   CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); | 
| 4057 } | 4057 } | 
| 4058 | 4058 | 
| 4059 | 4059 | 
| 4060 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { | 4060 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { | 
| 4061   Register input = ToRegister(instr->InputAt(0)); | 4061   Register input = ToRegister(instr->InputAt(0)); | 
| 4062   Register result = ToRegister(instr->result()); | 4062   Register result = ToRegister(instr->result()); | 
| 4063   Label true_label; | 4063   Label true_label; | 
| 4064   Label false_label; | 4064   Label false_label; | 
| 4065   NearLabel done; | 4065   Label done; | 
| 4066 | 4066 | 
| 4067   Condition final_branch_condition = EmitTypeofIs(&true_label, | 4067   Condition final_branch_condition = EmitTypeofIs(&true_label, | 
| 4068                                                   &false_label, | 4068                                                   &false_label, | 
| 4069                                                   input, | 4069                                                   input, | 
| 4070                                                   instr->type_literal()); | 4070                                                   instr->type_literal()); | 
| 4071   __ j(final_branch_condition, &true_label); | 4071   __ j(final_branch_condition, &true_label, Label::kNear); | 
| 4072   __ bind(&false_label); | 4072   __ bind(&false_label); | 
| 4073   __ mov(result, factory()->false_value()); | 4073   __ mov(result, factory()->false_value()); | 
| 4074   __ jmp(&done); | 4074   __ jmp(&done, Label::kNear); | 
| 4075 | 4075 | 
| 4076   __ bind(&true_label); | 4076   __ bind(&true_label); | 
| 4077   __ mov(result, factory()->true_value()); | 4077   __ mov(result, factory()->true_value()); | 
| 4078 | 4078 | 
| 4079   __ bind(&done); | 4079   __ bind(&done); | 
| 4080 } | 4080 } | 
| 4081 | 4081 | 
| 4082 | 4082 | 
| 4083 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 4083 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 
| 4084   Register input = ToRegister(instr->InputAt(0)); | 4084   Register input = ToRegister(instr->InputAt(0)); | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4158     __ jmp(false_label); | 4158     __ jmp(false_label); | 
| 4159     // A dead branch instruction will be generated after this point. | 4159     // A dead branch instruction will be generated after this point. | 
| 4160   } | 4160   } | 
| 4161 | 4161 | 
| 4162   return final_branch_condition; | 4162   return final_branch_condition; | 
| 4163 } | 4163 } | 
| 4164 | 4164 | 
| 4165 | 4165 | 
| 4166 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { | 4166 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { | 
| 4167   Register result = ToRegister(instr->result()); | 4167   Register result = ToRegister(instr->result()); | 
| 4168   NearLabel true_label; | 4168   Label true_label; | 
| 4169   NearLabel false_label; | 4169   Label done; | 
| 4170   NearLabel done; |  | 
| 4171 | 4170 | 
| 4172   EmitIsConstructCall(result); | 4171   EmitIsConstructCall(result); | 
| 4173   __ j(equal, &true_label); | 4172   __ j(equal, &true_label, Label::kNear); | 
| 4174 | 4173 | 
| 4175   __ mov(result, factory()->false_value()); | 4174   __ mov(result, factory()->false_value()); | 
| 4176   __ jmp(&done); | 4175   __ jmp(&done, Label::kNear); | 
| 4177 | 4176 | 
| 4178   __ bind(&true_label); | 4177   __ bind(&true_label); | 
| 4179   __ mov(result, factory()->true_value()); | 4178   __ mov(result, factory()->true_value()); | 
| 4180 | 4179 | 
| 4181   __ bind(&done); | 4180   __ bind(&done); | 
| 4182 } | 4181 } | 
| 4183 | 4182 | 
| 4184 | 4183 | 
| 4185 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4184 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 
| 4186   Register temp = ToRegister(instr->TempAt(0)); | 4185   Register temp = ToRegister(instr->TempAt(0)); | 
| 4187   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4186   int true_block = chunk_->LookupDestination(instr->true_block_id()); | 
| 4188   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4187   int false_block = chunk_->LookupDestination(instr->false_block_id()); | 
| 4189 | 4188 | 
| 4190   EmitIsConstructCall(temp); | 4189   EmitIsConstructCall(temp); | 
| 4191   EmitBranch(true_block, false_block, equal); | 4190   EmitBranch(true_block, false_block, equal); | 
| 4192 } | 4191 } | 
| 4193 | 4192 | 
| 4194 | 4193 | 
| 4195 void LCodeGen::EmitIsConstructCall(Register temp) { | 4194 void LCodeGen::EmitIsConstructCall(Register temp) { | 
| 4196   // Get the frame pointer for the calling frame. | 4195   // Get the frame pointer for the calling frame. | 
| 4197   __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 4196   __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 
| 4198 | 4197 | 
| 4199   // Skip the arguments adaptor frame if it exists. | 4198   // Skip the arguments adaptor frame if it exists. | 
| 4200   NearLabel check_frame_marker; | 4199   Label check_frame_marker; | 
| 4201   __ cmp(Operand(temp, StandardFrameConstants::kContextOffset), | 4200   __ cmp(Operand(temp, StandardFrameConstants::kContextOffset), | 
| 4202          Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 4201          Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 
| 4203   __ j(not_equal, &check_frame_marker); | 4202   __ j(not_equal, &check_frame_marker, Label::kNear); | 
| 4204   __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); | 4203   __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); | 
| 4205 | 4204 | 
| 4206   // Check the marker in the calling frame. | 4205   // Check the marker in the calling frame. | 
| 4207   __ bind(&check_frame_marker); | 4206   __ bind(&check_frame_marker); | 
| 4208   __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), | 4207   __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), | 
| 4209          Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); | 4208          Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); | 
| 4210 } | 4209 } | 
| 4211 | 4210 | 
| 4212 | 4211 | 
| 4213 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { | 4212 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 4242                                          pointers, | 4241                                          pointers, | 
| 4243                                          env->deoptimization_index()); | 4242                                          env->deoptimization_index()); | 
| 4244   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4243   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| 4245   __ push(Immediate(Smi::FromInt(strict_mode_flag()))); | 4244   __ push(Immediate(Smi::FromInt(strict_mode_flag()))); | 
| 4246   __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); | 4245   __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); | 
| 4247 } | 4246 } | 
| 4248 | 4247 | 
| 4249 | 4248 | 
| 4250 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 4249 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 
| 4251   // Perform stack overflow check. | 4250   // Perform stack overflow check. | 
| 4252   NearLabel done; | 4251   Label done; | 
| 4253   ExternalReference stack_limit = | 4252   ExternalReference stack_limit = | 
| 4254       ExternalReference::address_of_stack_limit(isolate()); | 4253       ExternalReference::address_of_stack_limit(isolate()); | 
| 4255   __ cmp(esp, Operand::StaticVariable(stack_limit)); | 4254   __ cmp(esp, Operand::StaticVariable(stack_limit)); | 
| 4256   __ j(above_equal, &done); | 4255   __ j(above_equal, &done, Label::kNear); | 
| 4257 | 4256 | 
| 4258   StackCheckStub stub; | 4257   StackCheckStub stub; | 
| 4259   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 4258   CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); | 
| 4260   __ bind(&done); | 4259   __ bind(&done); | 
| 4261 } | 4260 } | 
| 4262 | 4261 | 
| 4263 | 4262 | 
| 4264 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 4263 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 
| 4265   // This is a pseudo-instruction that ensures that the environment here is | 4264   // This is a pseudo-instruction that ensures that the environment here is | 
| 4266   // properly registered for deoptimization and records the assembler's PC | 4265   // properly registered for deoptimization and records the assembler's PC | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4305   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4304   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 
| 4306   __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 4305   __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); | 
| 4307 } | 4306 } | 
| 4308 | 4307 | 
| 4309 | 4308 | 
| 4310 #undef __ | 4309 #undef __ | 
| 4311 | 4310 | 
| 4312 } }  // namespace v8::internal | 4311 } }  // namespace v8::internal | 
| 4313 | 4312 | 
| 4314 #endif  // V8_TARGET_ARCH_IA32 | 4313 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|