OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 2100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2111 // Non-initializing assignments to consts are ignored. | 2111 // Non-initializing assignments to consts are ignored. |
2112 } | 2112 } |
2113 | 2113 |
2114 | 2114 |
2115 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2115 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2116 // Assignment to a property, using a named store IC. | 2116 // Assignment to a property, using a named store IC. |
2117 Property* prop = expr->target()->AsProperty(); | 2117 Property* prop = expr->target()->AsProperty(); |
2118 ASSERT(prop != NULL); | 2118 ASSERT(prop != NULL); |
2119 ASSERT(prop->key()->AsLiteral() != NULL); | 2119 ASSERT(prop->key()->AsLiteral() != NULL); |
2120 | 2120 |
| 2121 // If the assignment starts a block of assignments to the same object, |
| 2122 // change to slow case to avoid the quadratic behavior of repeatedly |
| 2123 // adding fast properties. |
| 2124 if (expr->starts_initialization_block()) { |
| 2125 __ push(result_register()); |
| 2126 __ push(Operand(rsp, kPointerSize)); // Receiver is now under value. |
| 2127 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 2128 __ pop(result_register()); |
| 2129 } |
| 2130 |
2121 // Record source code position before IC call. | 2131 // Record source code position before IC call. |
2122 SetSourcePosition(expr->position()); | 2132 SetSourcePosition(expr->position()); |
2123 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 2133 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
2124 __ pop(rdx); | 2134 if (expr->ends_initialization_block()) { |
| 2135 __ movq(rdx, Operand(rsp, 0)); |
| 2136 } else { |
| 2137 __ pop(rdx); |
| 2138 } |
2125 Handle<Code> ic = is_classic_mode() | 2139 Handle<Code> ic = is_classic_mode() |
2126 ? isolate()->builtins()->StoreIC_Initialize() | 2140 ? isolate()->builtins()->StoreIC_Initialize() |
2127 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 2141 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
2128 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2142 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
2129 | 2143 |
| 2144 // If the assignment ends an initialization block, revert to fast case. |
| 2145 if (expr->ends_initialization_block()) { |
| 2146 __ push(rax); // Result of assignment, saved even if not needed. |
| 2147 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
| 2148 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2149 __ pop(rax); |
| 2150 __ Drop(1); |
| 2151 } |
2130 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2152 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2131 context()->Plug(rax); | 2153 context()->Plug(rax); |
2132 } | 2154 } |
2133 | 2155 |
2134 | 2156 |
2135 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2157 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2136 // Assignment to a property, using a keyed store IC. | 2158 // Assignment to a property, using a keyed store IC. |
2137 | 2159 |
| 2160 // If the assignment starts a block of assignments to the same object, |
| 2161 // change to slow case to avoid the quadratic behavior of repeatedly |
| 2162 // adding fast properties. |
| 2163 if (expr->starts_initialization_block()) { |
| 2164 __ push(result_register()); |
| 2165 // Receiver is now under the key and value. |
| 2166 __ push(Operand(rsp, 2 * kPointerSize)); |
| 2167 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 2168 __ pop(result_register()); |
| 2169 } |
| 2170 |
2138 __ pop(rcx); | 2171 __ pop(rcx); |
2139 __ pop(rdx); | 2172 if (expr->ends_initialization_block()) { |
| 2173 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
| 2174 } else { |
| 2175 __ pop(rdx); |
| 2176 } |
2140 // Record source code position before IC call. | 2177 // Record source code position before IC call. |
2141 SetSourcePosition(expr->position()); | 2178 SetSourcePosition(expr->position()); |
2142 Handle<Code> ic = is_classic_mode() | 2179 Handle<Code> ic = is_classic_mode() |
2143 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2180 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2144 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2181 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2145 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2182 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); |
2146 | 2183 |
| 2184 // If the assignment ends an initialization block, revert to fast case. |
| 2185 if (expr->ends_initialization_block()) { |
| 2186 __ pop(rdx); |
| 2187 __ push(rax); // Result of assignment, saved even if not needed. |
| 2188 __ push(rdx); |
| 2189 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2190 __ pop(rax); |
| 2191 } |
| 2192 |
2147 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2193 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2148 context()->Plug(rax); | 2194 context()->Plug(rax); |
2149 } | 2195 } |
2150 | 2196 |
2151 | 2197 |
2152 void FullCodeGenerator::VisitProperty(Property* expr) { | 2198 void FullCodeGenerator::VisitProperty(Property* expr) { |
2153 Comment cmnt(masm_, "[ Property"); | 2199 Comment cmnt(masm_, "[ Property"); |
2154 Expression* key = expr->key(); | 2200 Expression* key = expr->key(); |
2155 | 2201 |
2156 if (key->IsPropertyName()) { | 2202 if (key->IsPropertyName()) { |
(...skipping 2357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4514 *context_length = 0; | 4560 *context_length = 0; |
4515 return previous_; | 4561 return previous_; |
4516 } | 4562 } |
4517 | 4563 |
4518 | 4564 |
4519 #undef __ | 4565 #undef __ |
4520 | 4566 |
4521 } } // namespace v8::internal | 4567 } } // namespace v8::internal |
4522 | 4568 |
4523 #endif // V8_TARGET_ARCH_X64 | 4569 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |