| 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 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1243 __ SmiUntag(right_); | 1243 __ SmiUntag(right_); |
| 1244 } | 1244 } |
| 1245 } else { | 1245 } else { |
| 1246 // We know we have SSE2 here because otherwise the label is not linked (see | 1246 // We know we have SSE2 here because otherwise the label is not linked (see |
| 1247 // NonSmiInputLabel). | 1247 // NonSmiInputLabel). |
| 1248 CpuFeatures::Scope use_sse2(SSE2); | 1248 CpuFeatures::Scope use_sse2(SSE2); |
| 1249 // Handle the non-constant right hand side situation: | 1249 // Handle the non-constant right hand side situation: |
| 1250 if (left_info_.IsSmi()) { | 1250 if (left_info_.IsSmi()) { |
| 1251 // Right is a heap object. | 1251 // Right is a heap object. |
| 1252 __ JumpIfNotNumber(right_, right_info_, entry_label()); | 1252 __ JumpIfNotNumber(right_, right_info_, entry_label()); |
| 1253 __ ConvertToInt32(right_, right_, dst_, left_info_, entry_label()); | 1253 __ ConvertToInt32(right_, right_, dst_, right_info_, entry_label()); |
| 1254 __ mov(dst_, Operand(left_)); | 1254 __ mov(dst_, Operand(left_)); |
| 1255 __ SmiUntag(dst_); | 1255 __ SmiUntag(dst_); |
| 1256 } else if (right_info_.IsSmi()) { | 1256 } else if (right_info_.IsSmi()) { |
| 1257 // Left is a heap object. | 1257 // Left is a heap object. |
| 1258 __ JumpIfNotNumber(left_, left_info_, entry_label()); | 1258 __ JumpIfNotNumber(left_, left_info_, entry_label()); |
| 1259 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); | 1259 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); |
| 1260 __ SmiUntag(right_); | 1260 __ SmiUntag(right_); |
| 1261 } else { | 1261 } else { |
| 1262 // Here we don't know if it's one or both that is a heap object. | 1262 // Here we don't know if it's one or both that is a heap object. |
| 1263 Label only_right_is_heap_object, got_both; | 1263 Label only_right_is_heap_object, got_both; |
| 1264 __ mov(dst_, Operand(left_)); | 1264 __ mov(dst_, Operand(left_)); |
| 1265 __ SmiUntag(dst_, &only_right_is_heap_object); | 1265 __ SmiUntag(dst_, &only_right_is_heap_object); |
| 1266 // Left was a heap object. | 1266 // Left was a heap object. |
| 1267 __ JumpIfNotNumber(left_, left_info_, entry_label()); | 1267 __ JumpIfNotNumber(left_, left_info_, entry_label()); |
| 1268 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); | 1268 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); |
| 1269 __ SmiUntag(right_, &got_both); | 1269 __ SmiUntag(right_, &got_both); |
| 1270 // Both were heap objects. | 1270 // Both were heap objects. |
| 1271 __ rcl(right_, 1); // Put tag back. | 1271 __ rcl(right_, 1); // Put tag back. |
| 1272 __ JumpIfNotNumber(right_, right_info_, entry_label()); | 1272 __ JumpIfNotNumber(right_, right_info_, entry_label()); |
| 1273 __ ConvertToInt32(right_, right_, no_reg, left_info_, entry_label()); | 1273 __ ConvertToInt32(right_, right_, no_reg, right_info_, entry_label()); |
| 1274 __ jmp(&got_both); | 1274 __ jmp(&got_both); |
| 1275 __ bind(&only_right_is_heap_object); | 1275 __ bind(&only_right_is_heap_object); |
| 1276 __ JumpIfNotNumber(right_, right_info_, entry_label()); | 1276 __ JumpIfNotNumber(right_, right_info_, entry_label()); |
| 1277 __ ConvertToInt32(right_, right_, no_reg, left_info_, entry_label()); | 1277 __ ConvertToInt32(right_, right_, no_reg, right_info_, entry_label()); |
| 1278 __ bind(&got_both); | 1278 __ bind(&got_both); |
| 1279 } | 1279 } |
| 1280 } | 1280 } |
| 1281 ASSERT(op_ == Token::BIT_AND || | 1281 ASSERT(op_ == Token::BIT_AND || |
| 1282 op_ == Token::BIT_OR || | 1282 op_ == Token::BIT_OR || |
| 1283 op_ == Token::BIT_XOR || | 1283 op_ == Token::BIT_XOR || |
| 1284 right_.is(ecx)); | 1284 right_.is(ecx)); |
| 1285 switch (op_) { | 1285 switch (op_) { |
| 1286 case Token::BIT_AND: __ and_(dst_, Operand(right_)); break; | 1286 case Token::BIT_AND: __ and_(dst_, Operand(right_)); break; |
| 1287 case Token::BIT_OR: __ or_(dst_, Operand(right_)); break; | 1287 case Token::BIT_OR: __ or_(dst_, Operand(right_)); break; |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 // We will modify right, it must be spilled. | 1933 // We will modify right, it must be spilled. |
| 1934 frame_->Spill(ecx); | 1934 frame_->Spill(ecx); |
| 1935 // DeferredInlineBinaryOperation requires all the registers that it is told | 1935 // DeferredInlineBinaryOperation requires all the registers that it is told |
| 1936 // about to be spilled and distinct. We know that right is ecx and left is | 1936 // about to be spilled and distinct. We know that right is ecx and left is |
| 1937 // not ecx. | 1937 // not ecx. |
| 1938 frame_->Spill(left->reg()); | 1938 frame_->Spill(left->reg()); |
| 1939 | 1939 |
| 1940 // Use a fresh answer register to avoid spilling the left operand. | 1940 // Use a fresh answer register to avoid spilling the left operand. |
| 1941 answer = allocator_->Allocate(); | 1941 answer = allocator_->Allocate(); |
| 1942 ASSERT(answer.is_valid()); | 1942 ASSERT(answer.is_valid()); |
| 1943 |
| 1943 DeferredInlineBinaryOperation* deferred = | 1944 DeferredInlineBinaryOperation* deferred = |
| 1944 new DeferredInlineBinaryOperation(op, | 1945 new DeferredInlineBinaryOperation(op, |
| 1945 answer.reg(), | 1946 answer.reg(), |
| 1946 left->reg(), | 1947 left->reg(), |
| 1947 ecx, | 1948 ecx, |
| 1948 left_type_info, | 1949 left_type_info, |
| 1949 right_type_info, | 1950 right_type_info, |
| 1950 overwrite_mode); | 1951 overwrite_mode); |
| 1951 JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), answer.reg(), | 1952 JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), answer.reg(), |
| 1952 left_type_info, right_type_info, | 1953 left_type_info, right_type_info, |
| (...skipping 2645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4598 | 4599 |
| 4599 // If the property has been removed while iterating, we just skip it. | 4600 // If the property has been removed while iterating, we just skip it. |
| 4600 __ test(ebx, Operand(ebx)); | 4601 __ test(ebx, Operand(ebx)); |
| 4601 node->continue_target()->Branch(equal); | 4602 node->continue_target()->Branch(equal); |
| 4602 | 4603 |
| 4603 end_del_check.Bind(); | 4604 end_del_check.Bind(); |
| 4604 // Store the entry in the 'each' expression and take another spin in the | 4605 // Store the entry in the 'each' expression and take another spin in the |
| 4605 // loop. edx: i'th entry of the enum cache (or string there of) | 4606 // loop. edx: i'th entry of the enum cache (or string there of) |
| 4606 frame_->EmitPush(ebx); | 4607 frame_->EmitPush(ebx); |
| 4607 { Reference each(this, node->each()); | 4608 { Reference each(this, node->each()); |
| 4608 // Loading a reference may leave the frame in an unspilled state. | |
| 4609 frame_->SpillAll(); | |
| 4610 if (!each.is_illegal()) { | 4609 if (!each.is_illegal()) { |
| 4611 if (each.size() > 0) { | 4610 if (each.size() > 0) { |
| 4611 // Loading a reference may leave the frame in an unspilled state. |
| 4612 frame_->SpillAll(); |
| 4613 // Get the value (under the reference on the stack) from memory. |
| 4612 frame_->EmitPush(frame_->ElementAt(each.size())); | 4614 frame_->EmitPush(frame_->ElementAt(each.size())); |
| 4613 each.SetValue(NOT_CONST_INIT); | 4615 each.SetValue(NOT_CONST_INIT); |
| 4614 frame_->Drop(2); | 4616 frame_->Drop(2); |
| 4615 } else { | 4617 } else { |
| 4616 // If the reference was to a slot we rely on the convenient property | 4618 // If the reference was to a slot we rely on the convenient property |
| 4617 // that it doesn't matter whether a value (eg, ebx pushed above) is | 4619 // that it doesn't matter whether a value (eg, ebx pushed above) is |
| 4618 // right on top of or right underneath a zero-sized reference. | 4620 // right on top of or right underneath a zero-sized reference. |
| 4619 each.SetValue(NOT_CONST_INIT); | 4621 each.SetValue(NOT_CONST_INIT); |
| 4620 frame_->Drop(); | 4622 frame_->Drop(); |
| 4621 } | 4623 } |
| (...skipping 9766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14388 masm.GetCode(&desc); | 14390 masm.GetCode(&desc); |
| 14389 // Call the function from C++. | 14391 // Call the function from C++. |
| 14390 return FUNCTION_CAST<MemCopyFunction>(buffer); | 14392 return FUNCTION_CAST<MemCopyFunction>(buffer); |
| 14391 } | 14393 } |
| 14392 | 14394 |
| 14393 #undef __ | 14395 #undef __ |
| 14394 | 14396 |
| 14395 } } // namespace v8::internal | 14397 } } // namespace v8::internal |
| 14396 | 14398 |
| 14397 #endif // V8_TARGET_ARCH_IA32 | 14399 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |