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 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1120 // Four cases: non-this global variables, lookup slots, all other | 1120 // Four cases: non-this global variables, lookup slots, all other |
1121 // types of slots, and parameters that rewrite to explicit property | 1121 // types of slots, and parameters that rewrite to explicit property |
1122 // accesses on the arguments object. | 1122 // accesses on the arguments object. |
1123 Slot* slot = var->slot(); | 1123 Slot* slot = var->slot(); |
1124 Property* property = var->AsProperty(); | 1124 Property* property = var->AsProperty(); |
1125 | 1125 |
1126 if (var->is_global() && !var->is_this()) { | 1126 if (var->is_global() && !var->is_this()) { |
1127 Comment cmnt(masm_, "Global variable"); | 1127 Comment cmnt(masm_, "Global variable"); |
1128 // Use inline caching. Variable name is passed in rcx and the global | 1128 // Use inline caching. Variable name is passed in rcx and the global |
1129 // object on the stack. | 1129 // object on the stack. |
1130 __ push(CodeGenerator::GlobalObject()); | |
1131 __ Move(rcx, var->name()); | 1130 __ Move(rcx, var->name()); |
| 1131 __ movq(rax, CodeGenerator::GlobalObject()); |
1132 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1132 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
1133 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1133 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1134 // A test rax instruction following the call is used by the IC to | 1134 // A test rax instruction following the call is used by the IC to |
1135 // indicate that the inobject property case was inlined. Ensure there | 1135 // indicate that the inobject property case was inlined. Ensure there |
1136 // is no test rax instruction here. | 1136 // is no test rax instruction here. |
1137 __ nop(); | 1137 __ nop(); |
1138 DropAndApply(1, context, rax); | 1138 Apply(context, rax); |
1139 | 1139 |
1140 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1140 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1141 Comment cmnt(masm_, "Lookup slot"); | 1141 Comment cmnt(masm_, "Lookup slot"); |
1142 __ push(rsi); // Context. | 1142 __ push(rsi); // Context. |
1143 __ Push(var->name()); | 1143 __ Push(var->name()); |
1144 __ CallRuntime(Runtime::kLoadContextSlot, 2); | 1144 __ CallRuntime(Runtime::kLoadContextSlot, 2); |
1145 Apply(context, rax); | 1145 Apply(context, rax); |
1146 | 1146 |
1147 } else if (slot != NULL) { | 1147 } else if (slot != NULL) { |
1148 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) | 1148 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1686 } | 1686 } |
1687 | 1687 |
1688 Apply(context_, rax); | 1688 Apply(context_, rax); |
1689 } | 1689 } |
1690 | 1690 |
1691 | 1691 |
1692 void FullCodeGenerator::VisitProperty(Property* expr) { | 1692 void FullCodeGenerator::VisitProperty(Property* expr) { |
1693 Comment cmnt(masm_, "[ Property"); | 1693 Comment cmnt(masm_, "[ Property"); |
1694 Expression* key = expr->key(); | 1694 Expression* key = expr->key(); |
1695 | 1695 |
1696 // Evaluate receiver. | |
1697 VisitForValue(expr->obj(), kStack); | |
1698 | |
1699 if (key->IsPropertyName()) { | 1696 if (key->IsPropertyName()) { |
| 1697 VisitForValue(expr->obj(), kAccumulator); |
1700 EmitNamedPropertyLoad(expr); | 1698 EmitNamedPropertyLoad(expr); |
1701 // Drop receiver left on the stack by IC. | 1699 Apply(context_, rax); |
1702 DropAndApply(1, context_, rax); | |
1703 } else { | 1700 } else { |
| 1701 VisitForValue(expr->obj(), kStack); |
1704 VisitForValue(expr->key(), kStack); | 1702 VisitForValue(expr->key(), kStack); |
1705 EmitKeyedPropertyLoad(expr); | 1703 EmitKeyedPropertyLoad(expr); |
1706 // Drop key and receiver left on the stack by IC. | 1704 // Drop key and receiver left on the stack by IC. |
1707 DropAndApply(2, context_, rax); | 1705 DropAndApply(2, context_, rax); |
1708 } | 1706 } |
1709 } | 1707 } |
1710 | 1708 |
1711 | 1709 |
1712 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 1710 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
1713 Handle<Object> name, | 1711 Handle<Object> name, |
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2738 break; | 2736 break; |
2739 } | 2737 } |
2740 | 2738 |
2741 case Token::TYPEOF: { | 2739 case Token::TYPEOF: { |
2742 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 2740 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
2743 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2741 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
2744 if (proxy != NULL && | 2742 if (proxy != NULL && |
2745 !proxy->var()->is_this() && | 2743 !proxy->var()->is_this() && |
2746 proxy->var()->is_global()) { | 2744 proxy->var()->is_global()) { |
2747 Comment cmnt(masm_, "Global variable"); | 2745 Comment cmnt(masm_, "Global variable"); |
2748 __ push(CodeGenerator::GlobalObject()); | |
2749 __ Move(rcx, proxy->name()); | 2746 __ Move(rcx, proxy->name()); |
| 2747 __ movq(rax, CodeGenerator::GlobalObject()); |
2750 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 2748 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
2751 // Use a regular load, not a contextual load, to avoid a reference | 2749 // Use a regular load, not a contextual load, to avoid a reference |
2752 // error. | 2750 // error. |
2753 __ Call(ic, RelocInfo::CODE_TARGET); | 2751 __ Call(ic, RelocInfo::CODE_TARGET); |
2754 __ movq(Operand(rsp, 0), rax); | 2752 __ push(rax); |
2755 } else if (proxy != NULL && | 2753 } else if (proxy != NULL && |
2756 proxy->var()->slot() != NULL && | 2754 proxy->var()->slot() != NULL && |
2757 proxy->var()->slot()->type() == Slot::LOOKUP) { | 2755 proxy->var()->slot()->type() == Slot::LOOKUP) { |
2758 __ push(rsi); | 2756 __ push(rsi); |
2759 __ Push(proxy->name()); | 2757 __ Push(proxy->name()); |
2760 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 2758 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
2761 __ push(rax); | 2759 __ push(rax); |
2762 } else { | 2760 } else { |
2763 // This expression cannot throw a reference error at the top level. | 2761 // This expression cannot throw a reference error at the top level. |
2764 VisitForValue(expr->expression(), kStack); | 2762 VisitForValue(expr->expression(), kStack); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2854 Location saved_location = location_; | 2852 Location saved_location = location_; |
2855 location_ = kAccumulator; | 2853 location_ = kAccumulator; |
2856 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), | 2854 EmitVariableLoad(expr->expression()->AsVariableProxy()->var(), |
2857 Expression::kValue); | 2855 Expression::kValue); |
2858 location_ = saved_location; | 2856 location_ = saved_location; |
2859 } else { | 2857 } else { |
2860 // Reserve space for result of postfix operation. | 2858 // Reserve space for result of postfix operation. |
2861 if (expr->is_postfix() && context_ != Expression::kEffect) { | 2859 if (expr->is_postfix() && context_ != Expression::kEffect) { |
2862 __ Push(Smi::FromInt(0)); | 2860 __ Push(Smi::FromInt(0)); |
2863 } | 2861 } |
2864 VisitForValue(prop->obj(), kStack); | |
2865 if (assign_type == NAMED_PROPERTY) { | 2862 if (assign_type == NAMED_PROPERTY) { |
| 2863 VisitForValue(prop->obj(), kAccumulator); |
| 2864 __ push(rax); // Copy of receiver, needed for later store. |
2866 EmitNamedPropertyLoad(prop); | 2865 EmitNamedPropertyLoad(prop); |
2867 } else { | 2866 } else { |
| 2867 VisitForValue(prop->obj(), kStack); |
2868 VisitForValue(prop->key(), kStack); | 2868 VisitForValue(prop->key(), kStack); |
2869 EmitKeyedPropertyLoad(prop); | 2869 EmitKeyedPropertyLoad(prop); |
2870 } | 2870 } |
2871 } | 2871 } |
2872 | 2872 |
2873 // Call ToNumber only if operand is not a smi. | 2873 // Call ToNumber only if operand is not a smi. |
2874 Label no_conversion; | 2874 Label no_conversion; |
2875 Condition is_smi; | 2875 Condition is_smi; |
2876 is_smi = masm_->CheckSmi(rax); | 2876 is_smi = masm_->CheckSmi(rax); |
2877 __ j(is_smi, &no_conversion); | 2877 __ j(is_smi, &no_conversion); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3214 __ ret(0); | 3214 __ ret(0); |
3215 } | 3215 } |
3216 | 3216 |
3217 | 3217 |
3218 #undef __ | 3218 #undef __ |
3219 | 3219 |
3220 | 3220 |
3221 } } // namespace v8::internal | 3221 } } // namespace v8::internal |
3222 | 3222 |
3223 #endif // V8_TARGET_ARCH_X64 | 3223 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |