OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 masm_->InstructionsGeneratedSince(&check_exit_codesize); | 239 masm_->InstructionsGeneratedSince(&check_exit_codesize); |
240 CHECK(return_sequence_length == | 240 CHECK(return_sequence_length == |
241 Assembler::kJSReturnSequenceInstructions || | 241 Assembler::kJSReturnSequenceInstructions || |
242 return_sequence_length == | 242 return_sequence_length == |
243 Assembler::kJSReturnSequenceInstructions + 1); | 243 Assembler::kJSReturnSequenceInstructions + 1); |
244 #endif | 244 #endif |
245 } | 245 } |
246 } | 246 } |
247 | 247 |
248 | 248 |
| 249 FullCodeGenerator::ConstantOperand FullCodeGenerator::GetConstantOperand( |
| 250 Token::Value op, Expression* left, Expression* right) { |
| 251 ASSERT(ShouldInlineSmiCase(op)); |
| 252 return kNoConstants; |
| 253 } |
| 254 |
| 255 |
249 void FullCodeGenerator::Apply(Expression::Context context, Register reg) { | 256 void FullCodeGenerator::Apply(Expression::Context context, Register reg) { |
250 switch (context) { | 257 switch (context) { |
251 case Expression::kUninitialized: | 258 case Expression::kUninitialized: |
252 UNREACHABLE(); | 259 UNREACHABLE(); |
253 | 260 |
254 case Expression::kEffect: | 261 case Expression::kEffect: |
255 // Nothing to do. | 262 // Nothing to do. |
256 break; | 263 break; |
257 | 264 |
258 case Expression::kValue: | 265 case Expression::kValue: |
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 // on the left-hand side. | 1144 // on the left-hand side. |
1138 if (!expr->target()->IsValidLeftHandSide()) { | 1145 if (!expr->target()->IsValidLeftHandSide()) { |
1139 VisitForEffect(expr->target()); | 1146 VisitForEffect(expr->target()); |
1140 return; | 1147 return; |
1141 } | 1148 } |
1142 | 1149 |
1143 // Left-hand side can only be a property, a global or a (parameter or local) | 1150 // Left-hand side can only be a property, a global or a (parameter or local) |
1144 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. | 1151 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. |
1145 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 1152 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
1146 LhsKind assign_type = VARIABLE; | 1153 LhsKind assign_type = VARIABLE; |
1147 Property* prop = expr->target()->AsProperty(); | 1154 Property* property = expr->target()->AsProperty(); |
1148 if (prop != NULL) { | 1155 if (property != NULL) { |
1149 assign_type = | 1156 assign_type = (property->key()->IsPropertyName()) |
1150 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; | 1157 ? NAMED_PROPERTY |
| 1158 : KEYED_PROPERTY; |
1151 } | 1159 } |
1152 | 1160 |
1153 // Evaluate LHS expression. | 1161 // Evaluate LHS expression. |
1154 switch (assign_type) { | 1162 switch (assign_type) { |
1155 case VARIABLE: | 1163 case VARIABLE: |
1156 // Nothing to do here. | 1164 // Nothing to do here. |
1157 break; | 1165 break; |
1158 case NAMED_PROPERTY: | 1166 case NAMED_PROPERTY: |
1159 if (expr->is_compound()) { | 1167 if (expr->is_compound()) { |
1160 // We need the receiver both on the stack and in the accumulator. | 1168 // We need the receiver both on the stack and in the accumulator. |
1161 VisitForValue(prop->obj(), kAccumulator); | 1169 VisitForValue(property->obj(), kAccumulator); |
1162 __ push(result_register()); | 1170 __ push(result_register()); |
1163 } else { | 1171 } else { |
1164 VisitForValue(prop->obj(), kStack); | 1172 VisitForValue(property->obj(), kStack); |
1165 } | 1173 } |
1166 break; | 1174 break; |
1167 case KEYED_PROPERTY: | 1175 case KEYED_PROPERTY: |
1168 // We need the key and receiver on both the stack and in r0 and r1. | |
1169 if (expr->is_compound()) { | 1176 if (expr->is_compound()) { |
1170 VisitForValue(prop->obj(), kStack); | 1177 VisitForValue(property->obj(), kStack); |
1171 VisitForValue(prop->key(), kAccumulator); | 1178 VisitForValue(property->key(), kAccumulator); |
1172 __ ldr(r1, MemOperand(sp, 0)); | 1179 __ ldr(r1, MemOperand(sp, 0)); |
1173 __ push(r0); | 1180 __ push(r0); |
1174 } else { | 1181 } else { |
1175 VisitForValue(prop->obj(), kStack); | 1182 VisitForValue(property->obj(), kStack); |
1176 VisitForValue(prop->key(), kStack); | 1183 VisitForValue(property->key(), kStack); |
1177 } | 1184 } |
1178 break; | 1185 break; |
1179 } | 1186 } |
1180 | 1187 |
1181 // If we have a compound assignment: Get value of LHS expression and | |
1182 // store in on top of the stack. | |
1183 if (expr->is_compound()) { | 1188 if (expr->is_compound()) { |
1184 Location saved_location = location_; | 1189 Location saved_location = location_; |
1185 location_ = kStack; | 1190 location_ = kAccumulator; |
1186 switch (assign_type) { | 1191 switch (assign_type) { |
1187 case VARIABLE: | 1192 case VARIABLE: |
1188 EmitVariableLoad(expr->target()->AsVariableProxy()->var(), | 1193 EmitVariableLoad(expr->target()->AsVariableProxy()->var(), |
1189 Expression::kValue); | 1194 Expression::kValue); |
1190 break; | 1195 break; |
1191 case NAMED_PROPERTY: | 1196 case NAMED_PROPERTY: |
1192 EmitNamedPropertyLoad(prop); | 1197 EmitNamedPropertyLoad(property); |
1193 __ push(result_register()); | |
1194 break; | 1198 break; |
1195 case KEYED_PROPERTY: | 1199 case KEYED_PROPERTY: |
1196 EmitKeyedPropertyLoad(prop); | 1200 EmitKeyedPropertyLoad(property); |
1197 __ push(result_register()); | |
1198 break; | 1201 break; |
1199 } | 1202 } |
1200 location_ = saved_location; | |
1201 } | |
1202 | 1203 |
1203 // Evaluate RHS expression. | 1204 Token::Value op = expr->binary_op(); |
1204 Expression* rhs = expr->value(); | 1205 ConstantOperand constant = ShouldInlineSmiCase(op) |
1205 VisitForValue(rhs, kAccumulator); | 1206 ? GetConstantOperand(op, expr->target(), expr->value()) |
| 1207 : kNoConstants; |
| 1208 ASSERT(constant == kRightConstant || constant == kNoConstants); |
| 1209 if (constant == kNoConstants) { |
| 1210 __ push(r0); // Left operand goes on the stack. |
| 1211 VisitForValue(expr->value(), kAccumulator); |
| 1212 } |
1206 | 1213 |
1207 // If we have a compound assignment: Apply operator. | |
1208 if (expr->is_compound()) { | |
1209 Location saved_location = location_; | |
1210 location_ = kAccumulator; | |
1211 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() | 1214 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() |
1212 ? OVERWRITE_RIGHT | 1215 ? OVERWRITE_RIGHT |
1213 : NO_OVERWRITE; | 1216 : NO_OVERWRITE; |
1214 EmitBinaryOp(expr->binary_op(), Expression::kValue, mode); | 1217 SetSourcePosition(expr->position() + 1); |
| 1218 if (ShouldInlineSmiCase(op)) { |
| 1219 EmitInlineSmiBinaryOp(expr, |
| 1220 op, |
| 1221 Expression::kValue, |
| 1222 mode, |
| 1223 expr->target(), |
| 1224 expr->value(), |
| 1225 constant); |
| 1226 } else { |
| 1227 EmitBinaryOp(op, Expression::kValue, mode); |
| 1228 } |
1215 location_ = saved_location; | 1229 location_ = saved_location; |
| 1230 |
| 1231 } else { |
| 1232 VisitForValue(expr->value(), kAccumulator); |
1216 } | 1233 } |
1217 | 1234 |
1218 // Record source position before possible IC call. | 1235 // Record source position before possible IC call. |
1219 SetSourcePosition(expr->position()); | 1236 SetSourcePosition(expr->position()); |
1220 | 1237 |
1221 // Store the value. | 1238 // Store the value. |
1222 switch (assign_type) { | 1239 switch (assign_type) { |
1223 case VARIABLE: | 1240 case VARIABLE: |
1224 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 1241 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
1225 expr->op(), | 1242 expr->op(), |
(...skipping 20 matching lines...) Expand all Loading... |
1246 | 1263 |
1247 | 1264 |
1248 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1265 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1249 SetSourcePosition(prop->position()); | 1266 SetSourcePosition(prop->position()); |
1250 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1267 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1251 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 1268 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
1252 __ Call(ic, RelocInfo::CODE_TARGET); | 1269 __ Call(ic, RelocInfo::CODE_TARGET); |
1253 } | 1270 } |
1254 | 1271 |
1255 | 1272 |
| 1273 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, |
| 1274 Token::Value op, |
| 1275 Expression::Context context, |
| 1276 OverwriteMode mode, |
| 1277 Expression* left, |
| 1278 Expression* right, |
| 1279 ConstantOperand constant) { |
| 1280 ASSERT(constant == kNoConstants); // Only handled case. |
| 1281 EmitBinaryOp(op, context, mode); |
| 1282 } |
| 1283 |
| 1284 |
1256 void FullCodeGenerator::EmitBinaryOp(Token::Value op, | 1285 void FullCodeGenerator::EmitBinaryOp(Token::Value op, |
1257 Expression::Context context, | 1286 Expression::Context context, |
1258 OverwriteMode mode) { | 1287 OverwriteMode mode) { |
1259 __ pop(r1); | 1288 __ pop(r1); |
1260 GenericBinaryOpStub stub(op, mode, r1, r0); | 1289 GenericBinaryOpStub stub(op, mode, r1, r0); |
1261 __ CallStub(&stub); | 1290 __ CallStub(&stub); |
1262 Apply(context, r0); | 1291 Apply(context, r0); |
1263 } | 1292 } |
1264 | 1293 |
1265 | 1294 |
(...skipping 1893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3159 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 3188 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
3160 __ add(pc, r1, Operand(masm_->CodeObject())); | 3189 __ add(pc, r1, Operand(masm_->CodeObject())); |
3161 } | 3190 } |
3162 | 3191 |
3163 | 3192 |
3164 #undef __ | 3193 #undef __ |
3165 | 3194 |
3166 } } // namespace v8::internal | 3195 } } // namespace v8::internal |
3167 | 3196 |
3168 #endif // V8_TARGET_ARCH_ARM | 3197 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |