| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 } | 670 } |
| 671 | 671 |
| 672 Comment cmnt(masm_, "[ Case comparison"); | 672 Comment cmnt(masm_, "[ Case comparison"); |
| 673 __ bind(&next_test); | 673 __ bind(&next_test); |
| 674 next_test.Unuse(); | 674 next_test.Unuse(); |
| 675 | 675 |
| 676 // Compile the label expression. | 676 // Compile the label expression. |
| 677 VisitForValue(clause->label(), kAccumulator); | 677 VisitForValue(clause->label(), kAccumulator); |
| 678 | 678 |
| 679 // Perform the comparison as if via '==='. | 679 // Perform the comparison as if via '==='. |
| 680 if (ShouldInlineSmiCase(Token::EQ_STRICT)) { | 680 __ movq(rdx, Operand(rsp, 0)); // Switch value. |
| 681 bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT); |
| 682 if (inline_smi_code) { |
| 681 Label slow_case; | 683 Label slow_case; |
| 682 __ movq(rdx, Operand(rsp, 0)); // Switch value. | |
| 683 __ JumpIfNotBothSmi(rdx, rax, &slow_case); | 684 __ JumpIfNotBothSmi(rdx, rax, &slow_case); |
| 684 __ SmiCompare(rdx, rax); | 685 __ SmiCompare(rdx, rax); |
| 685 __ j(not_equal, &next_test); | 686 __ j(not_equal, &next_test); |
| 686 __ Drop(1); // Switch value is no longer needed. | 687 __ Drop(1); // Switch value is no longer needed. |
| 687 __ jmp(clause->body_target()->entry_label()); | 688 __ jmp(clause->body_target()->entry_label()); |
| 688 __ bind(&slow_case); | 689 __ bind(&slow_case); |
| 689 } | 690 } |
| 690 | 691 |
| 691 CompareStub stub(equal, true); | 692 CompareFlags flags = inline_smi_code |
| 693 ? NO_SMI_COMPARE_IN_STUB |
| 694 : NO_COMPARE_FLAGS; |
| 695 CompareStub stub(equal, true, flags); |
| 692 __ CallStub(&stub); | 696 __ CallStub(&stub); |
| 693 __ testq(rax, rax); | 697 __ testq(rax, rax); |
| 694 __ j(not_equal, &next_test); | 698 __ j(not_equal, &next_test); |
| 695 __ Drop(1); // Switch value is no longer needed. | 699 __ Drop(1); // Switch value is no longer needed. |
| 696 __ jmp(clause->body_target()->entry_label()); | 700 __ jmp(clause->body_target()->entry_label()); |
| 697 } | 701 } |
| 698 | 702 |
| 699 // Discard the test value and jump to the default if present, otherwise to | 703 // Discard the test value and jump to the default if present, otherwise to |
| 700 // the end of the statement. | 704 // the end of the statement. |
| 701 __ bind(&next_test); | 705 __ bind(&next_test); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 | 935 |
| 932 // All extension objects were empty and it is safe to use a global | 936 // All extension objects were empty and it is safe to use a global |
| 933 // load IC call. | 937 // load IC call. |
| 934 __ movq(rax, CodeGenerator::GlobalObject()); | 938 __ movq(rax, CodeGenerator::GlobalObject()); |
| 935 __ Move(rcx, slot->var()->name()); | 939 __ Move(rcx, slot->var()->name()); |
| 936 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 940 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 937 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 941 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 938 ? RelocInfo::CODE_TARGET | 942 ? RelocInfo::CODE_TARGET |
| 939 : RelocInfo::CODE_TARGET_CONTEXT; | 943 : RelocInfo::CODE_TARGET_CONTEXT; |
| 940 __ call(ic, mode); | 944 __ call(ic, mode); |
| 945 __ nop(); // Signal no inlined code. |
| 941 } | 946 } |
| 942 | 947 |
| 943 | 948 |
| 944 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 949 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
| 945 Slot* slot, | 950 Slot* slot, |
| 946 Label* slow) { | 951 Label* slow) { |
| 947 ASSERT(slot->type() == Slot::CONTEXT); | 952 ASSERT(slot->type() == Slot::CONTEXT); |
| 948 Register context = rsi; | 953 Register context = rsi; |
| 949 Register temp = rbx; | 954 Register temp = rbx; |
| 950 | 955 |
| (...skipping 1996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2947 __ bind(&no_conversion); | 2952 __ bind(&no_conversion); |
| 2948 Apply(context_, result_register()); | 2953 Apply(context_, result_register()); |
| 2949 break; | 2954 break; |
| 2950 } | 2955 } |
| 2951 | 2956 |
| 2952 case Token::SUB: { | 2957 case Token::SUB: { |
| 2953 Comment cmt(masm_, "[ UnaryOperation (SUB)"); | 2958 Comment cmt(masm_, "[ UnaryOperation (SUB)"); |
| 2954 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 2959 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 2955 UnaryOverwriteMode overwrite = | 2960 UnaryOverwriteMode overwrite = |
| 2956 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 2961 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 2957 GenericUnaryOpStub stub(Token::SUB, overwrite); | 2962 GenericUnaryOpStub stub(Token::SUB, overwrite, NO_UNARY_FLAGS); |
| 2958 // GenericUnaryOpStub expects the argument to be in the | 2963 // GenericUnaryOpStub expects the argument to be in the |
| 2959 // accumulator register rax. | 2964 // accumulator register rax. |
| 2960 VisitForValue(expr->expression(), kAccumulator); | 2965 VisitForValue(expr->expression(), kAccumulator); |
| 2961 __ CallStub(&stub); | 2966 __ CallStub(&stub); |
| 2962 Apply(context_, rax); | 2967 Apply(context_, rax); |
| 2963 break; | 2968 break; |
| 2964 } | 2969 } |
| 2965 | 2970 |
| 2966 case Token::BIT_NOT: { | 2971 case Token::BIT_NOT: { |
| 2967 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); | 2972 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); |
| 2968 // The generic unary operation stub expects the argument to be | 2973 // The generic unary operation stub expects the argument to be |
| 2969 // in the accumulator register rax. | 2974 // in the accumulator register rax. |
| 2970 VisitForValue(expr->expression(), kAccumulator); | 2975 VisitForValue(expr->expression(), kAccumulator); |
| 2971 Label done; | 2976 Label done; |
| 2972 if (ShouldInlineSmiCase(expr->op())) { | 2977 bool inline_smi_case = ShouldInlineSmiCase(expr->op()); |
| 2978 if (inline_smi_case) { |
| 2973 Label call_stub; | 2979 Label call_stub; |
| 2974 __ JumpIfNotSmi(rax, &call_stub); | 2980 __ JumpIfNotSmi(rax, &call_stub); |
| 2975 __ SmiNot(rax, rax); | 2981 __ SmiNot(rax, rax); |
| 2976 __ jmp(&done); | 2982 __ jmp(&done); |
| 2977 __ bind(&call_stub); | 2983 __ bind(&call_stub); |
| 2978 } | 2984 } |
| 2979 bool overwrite = expr->expression()->ResultOverwriteAllowed(); | 2985 bool overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 2980 UnaryOverwriteMode mode = | 2986 UnaryOverwriteMode mode = |
| 2981 overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 2987 overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 2982 GenericUnaryOpStub stub(Token::BIT_NOT, mode); | 2988 UnaryOpFlags flags = inline_smi_case |
| 2989 ? NO_UNARY_SMI_CODE_IN_STUB |
| 2990 : NO_UNARY_FLAGS; |
| 2991 GenericUnaryOpStub stub(Token::BIT_NOT, mode, flags); |
| 2983 __ CallStub(&stub); | 2992 __ CallStub(&stub); |
| 2984 __ bind(&done); | 2993 __ bind(&done); |
| 2985 Apply(context_, rax); | 2994 Apply(context_, rax); |
| 2986 break; | 2995 break; |
| 2987 } | 2996 } |
| 2988 | 2997 |
| 2989 default: | 2998 default: |
| 2990 UNREACHABLE(); | 2999 UNREACHABLE(); |
| 2991 } | 3000 } |
| 2992 } | 3001 } |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3167 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { | 3176 void FullCodeGenerator::VisitForTypeofValue(Expression* expr, Location where) { |
| 3168 VariableProxy* proxy = expr->AsVariableProxy(); | 3177 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3169 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3178 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3170 Comment cmnt(masm_, "Global variable"); | 3179 Comment cmnt(masm_, "Global variable"); |
| 3171 __ Move(rcx, proxy->name()); | 3180 __ Move(rcx, proxy->name()); |
| 3172 __ movq(rax, CodeGenerator::GlobalObject()); | 3181 __ movq(rax, CodeGenerator::GlobalObject()); |
| 3173 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 3182 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 3174 // Use a regular load, not a contextual load, to avoid a reference | 3183 // Use a regular load, not a contextual load, to avoid a reference |
| 3175 // error. | 3184 // error. |
| 3176 __ Call(ic, RelocInfo::CODE_TARGET); | 3185 __ Call(ic, RelocInfo::CODE_TARGET); |
| 3186 __ nop(); // Signal no inlined code. |
| 3177 if (where == kStack) __ push(rax); | 3187 if (where == kStack) __ push(rax); |
| 3178 } else if (proxy != NULL && | 3188 } else if (proxy != NULL && |
| 3179 proxy->var()->slot() != NULL && | 3189 proxy->var()->slot() != NULL && |
| 3180 proxy->var()->slot()->type() == Slot::LOOKUP) { | 3190 proxy->var()->slot()->type() == Slot::LOOKUP) { |
| 3181 Label done, slow; | 3191 Label done, slow; |
| 3182 | 3192 |
| 3183 // Generate code for loading from variables potentially shadowed | 3193 // Generate code for loading from variables potentially shadowed |
| 3184 // by eval-introduced variables. | 3194 // by eval-introduced variables. |
| 3185 Slot* slot = proxy->var()->slot(); | 3195 Slot* slot = proxy->var()->slot(); |
| 3186 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); | 3196 EmitDynamicLoadFromSlotFastCase(slot, INSIDE_TYPEOF, &slow, &done); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3354 case Token::GTE: | 3364 case Token::GTE: |
| 3355 cc = greater_equal; | 3365 cc = greater_equal; |
| 3356 __ pop(rdx); | 3366 __ pop(rdx); |
| 3357 break; | 3367 break; |
| 3358 case Token::IN: | 3368 case Token::IN: |
| 3359 case Token::INSTANCEOF: | 3369 case Token::INSTANCEOF: |
| 3360 default: | 3370 default: |
| 3361 UNREACHABLE(); | 3371 UNREACHABLE(); |
| 3362 } | 3372 } |
| 3363 | 3373 |
| 3364 if (ShouldInlineSmiCase(op)) { | 3374 bool inline_smi_code = ShouldInlineSmiCase(op); |
| 3375 if (inline_smi_code) { |
| 3365 Label slow_case; | 3376 Label slow_case; |
| 3366 __ JumpIfNotBothSmi(rax, rdx, &slow_case); | 3377 __ JumpIfNotBothSmi(rax, rdx, &slow_case); |
| 3367 __ SmiCompare(rdx, rax); | 3378 __ SmiCompare(rdx, rax); |
| 3368 Split(cc, if_true, if_false, NULL); | 3379 Split(cc, if_true, if_false, NULL); |
| 3369 __ bind(&slow_case); | 3380 __ bind(&slow_case); |
| 3370 } | 3381 } |
| 3371 | 3382 |
| 3372 CompareStub stub(cc, strict); | 3383 CompareFlags flags = inline_smi_code |
| 3384 ? NO_SMI_COMPARE_IN_STUB |
| 3385 : NO_COMPARE_FLAGS; |
| 3386 CompareStub stub(cc, strict, flags); |
| 3373 __ CallStub(&stub); | 3387 __ CallStub(&stub); |
| 3374 __ testq(rax, rax); | 3388 __ testq(rax, rax); |
| 3375 Split(cc, if_true, if_false, fall_through); | 3389 Split(cc, if_true, if_false, fall_through); |
| 3376 } | 3390 } |
| 3377 } | 3391 } |
| 3378 | 3392 |
| 3379 // Convert the result of the comparison into one expected for this | 3393 // Convert the result of the comparison into one expected for this |
| 3380 // expression's context. | 3394 // expression's context. |
| 3381 Apply(context_, if_true, if_false); | 3395 Apply(context_, if_true, if_false); |
| 3382 } | 3396 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3467 __ ret(0); | 3481 __ ret(0); |
| 3468 } | 3482 } |
| 3469 | 3483 |
| 3470 | 3484 |
| 3471 #undef __ | 3485 #undef __ |
| 3472 | 3486 |
| 3473 | 3487 |
| 3474 } } // namespace v8::internal | 3488 } } // namespace v8::internal |
| 3475 | 3489 |
| 3476 #endif // V8_TARGET_ARCH_X64 | 3490 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |