Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 1905002: Make sure that type info of results is correctly recorded when results are mo... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/x64/codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 TypeInfo left_info, TypeInfo right_info, 1419 TypeInfo left_info, TypeInfo right_info,
1420 DeferredInlineBinaryOperation* deferred); 1420 DeferredInlineBinaryOperation* deferred);
1421 1421
1422 1422
1423 // Implements a binary operation using a deferred code object and some 1423 // Implements a binary operation using a deferred code object and some
1424 // inline code to operate on smis quickly. 1424 // inline code to operate on smis quickly.
1425 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, 1425 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
1426 Result* left, 1426 Result* left,
1427 Result* right, 1427 Result* right,
1428 OverwriteMode overwrite_mode) { 1428 OverwriteMode overwrite_mode) {
1429 // Copy the type info because left and right may be overwritten.
1430 TypeInfo left_type_info = left->type_info();
1431 TypeInfo right_type_info = right->type_info();
1429 Token::Value op = expr->op(); 1432 Token::Value op = expr->op();
1430 Result answer; 1433 Result answer;
1431 // Special handling of div and mod because they use fixed registers. 1434 // Special handling of div and mod because they use fixed registers.
1432 if (op == Token::DIV || op == Token::MOD) { 1435 if (op == Token::DIV || op == Token::MOD) {
1433 // We need eax as the quotient register, edx as the remainder 1436 // We need eax as the quotient register, edx as the remainder
1434 // register, neither left nor right in eax or edx, and left copied 1437 // register, neither left nor right in eax or edx, and left copied
1435 // to eax. 1438 // to eax.
1436 Result quotient; 1439 Result quotient;
1437 Result remainder; 1440 Result remainder;
1438 bool left_is_in_eax = false; 1441 bool left_is_in_eax = false;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1494 right->ToRegister(); 1497 right->ToRegister();
1495 frame_->Spill(eax); 1498 frame_->Spill(eax);
1496 frame_->Spill(edx); 1499 frame_->Spill(edx);
1497 1500
1498 // Check that left and right are smi tagged. 1501 // Check that left and right are smi tagged.
1499 DeferredInlineBinaryOperation* deferred = 1502 DeferredInlineBinaryOperation* deferred =
1500 new DeferredInlineBinaryOperation(op, 1503 new DeferredInlineBinaryOperation(op,
1501 (op == Token::DIV) ? eax : edx, 1504 (op == Token::DIV) ? eax : edx,
1502 left->reg(), 1505 left->reg(),
1503 right->reg(), 1506 right->reg(),
1504 left->type_info(), 1507 left_type_info,
1505 right->type_info(), 1508 right_type_info,
1506 overwrite_mode); 1509 overwrite_mode);
1507 if (left->reg().is(right->reg())) { 1510 if (left->reg().is(right->reg())) {
1508 __ test(left->reg(), Immediate(kSmiTagMask)); 1511 __ test(left->reg(), Immediate(kSmiTagMask));
1509 } else { 1512 } else {
1510 // Use the quotient register as a scratch for the tag check. 1513 // Use the quotient register as a scratch for the tag check.
1511 if (!left_is_in_eax) __ mov(eax, left->reg()); 1514 if (!left_is_in_eax) __ mov(eax, left->reg());
1512 left_is_in_eax = false; // About to destroy the value in eax. 1515 left_is_in_eax = false; // About to destroy the value in eax.
1513 __ or_(eax, Operand(right->reg())); 1516 __ or_(eax, Operand(right->reg()));
1514 ASSERT(kSmiTag == 0); // Adjust test if not the case. 1517 ASSERT(kSmiTag == 0); // Adjust test if not the case.
1515 __ test(eax, Immediate(kSmiTagMask)); 1518 __ test(eax, Immediate(kSmiTagMask));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 // Use a fresh answer register to avoid spilling the left operand. 1601 // Use a fresh answer register to avoid spilling the left operand.
1599 answer = allocator_->Allocate(); 1602 answer = allocator_->Allocate();
1600 ASSERT(answer.is_valid()); 1603 ASSERT(answer.is_valid());
1601 // Check that both operands are smis using the answer register as a 1604 // Check that both operands are smis using the answer register as a
1602 // temporary. 1605 // temporary.
1603 DeferredInlineBinaryOperation* deferred = 1606 DeferredInlineBinaryOperation* deferred =
1604 new DeferredInlineBinaryOperation(op, 1607 new DeferredInlineBinaryOperation(op,
1605 answer.reg(), 1608 answer.reg(),
1606 left->reg(), 1609 left->reg(),
1607 ecx, 1610 ecx,
1608 left->type_info(), 1611 left_type_info,
1609 right->type_info(), 1612 right_type_info,
1610 overwrite_mode); 1613 overwrite_mode);
1611 1614
1612 Label do_op, left_nonsmi; 1615 Label do_op, left_nonsmi;
1613 // If right is a smi we make a fast case if left is either a smi 1616 // If right is a smi we make a fast case if left is either a smi
1614 // or a heapnumber. 1617 // or a heapnumber.
1615 if (CpuFeatures::IsSupported(SSE2) && right->type_info().IsSmi()) { 1618 if (CpuFeatures::IsSupported(SSE2) && right_type_info.IsSmi()) {
1616 CpuFeatures::Scope use_sse2(SSE2); 1619 CpuFeatures::Scope use_sse2(SSE2);
1617 __ mov(answer.reg(), left->reg()); 1620 __ mov(answer.reg(), left->reg());
1618 // Fast case - both are actually smis. 1621 // Fast case - both are actually smis.
1619 if (!left->type_info().IsSmi()) { 1622 if (!left_type_info.IsSmi()) {
1620 __ test(answer.reg(), Immediate(kSmiTagMask)); 1623 __ test(answer.reg(), Immediate(kSmiTagMask));
1621 __ j(not_zero, &left_nonsmi); 1624 __ j(not_zero, &left_nonsmi);
1622 } else { 1625 } else {
1623 if (FLAG_debug_code) __ AbortIfNotSmi(left->reg()); 1626 if (FLAG_debug_code) __ AbortIfNotSmi(left->reg());
1624 } 1627 }
1625 if (FLAG_debug_code) __ AbortIfNotSmi(right->reg()); 1628 if (FLAG_debug_code) __ AbortIfNotSmi(right->reg());
1626 __ SmiUntag(answer.reg()); 1629 __ SmiUntag(answer.reg());
1627 __ jmp(&do_op); 1630 __ jmp(&do_op);
1628 1631
1629 __ bind(&left_nonsmi); 1632 __ bind(&left_nonsmi);
1630 // Branch if not a heapnumber. 1633 // Branch if not a heapnumber.
1631 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), 1634 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset),
1632 Factory::heap_number_map()); 1635 Factory::heap_number_map());
1633 deferred->Branch(not_equal); 1636 deferred->Branch(not_equal);
1634 1637
1635 // Load integer value into answer register using truncation. 1638 // Load integer value into answer register using truncation.
1636 __ cvttsd2si(answer.reg(), 1639 __ cvttsd2si(answer.reg(),
1637 FieldOperand(answer.reg(), HeapNumber::kValueOffset)); 1640 FieldOperand(answer.reg(), HeapNumber::kValueOffset));
1638 // Branch if we do not fit in a smi. 1641 // Branch if we do not fit in a smi.
1639 __ cmp(answer.reg(), 0xc0000000); 1642 __ cmp(answer.reg(), 0xc0000000);
1640 deferred->Branch(negative); 1643 deferred->Branch(negative);
1641 } else { 1644 } else {
1642 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), 1645 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
1643 left->type_info(), right->type_info(), deferred); 1646 left_type_info, right_type_info, deferred);
1644 1647
1645 // Untag both operands. 1648 // Untag both operands.
1646 __ mov(answer.reg(), left->reg()); 1649 __ mov(answer.reg(), left->reg());
1647 __ SmiUntag(answer.reg()); 1650 __ SmiUntag(answer.reg());
1648 } 1651 }
1649 1652
1650 __ bind(&do_op); 1653 __ bind(&do_op);
1651 __ SmiUntag(ecx); 1654 __ SmiUntag(ecx);
1652 // Perform the operation. 1655 // Perform the operation.
1653 switch (op) { 1656 switch (op) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 // need to be spilled in the fast case. 1709 // need to be spilled in the fast case.
1707 answer = allocator_->Allocate(); 1710 answer = allocator_->Allocate();
1708 ASSERT(answer.is_valid()); 1711 ASSERT(answer.is_valid());
1709 1712
1710 // Perform the smi tag check. 1713 // Perform the smi tag check.
1711 DeferredInlineBinaryOperation* deferred = 1714 DeferredInlineBinaryOperation* deferred =
1712 new DeferredInlineBinaryOperation(op, 1715 new DeferredInlineBinaryOperation(op,
1713 answer.reg(), 1716 answer.reg(),
1714 left->reg(), 1717 left->reg(),
1715 right->reg(), 1718 right->reg(),
1716 left->type_info(), 1719 left_type_info,
1717 right->type_info(), 1720 right_type_info,
1718 overwrite_mode); 1721 overwrite_mode);
1719 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(), 1722 CheckTwoForSminess(masm_, left->reg(), right->reg(), answer.reg(),
1720 left->type_info(), right->type_info(), deferred); 1723 left_type_info, right_type_info, deferred);
1721 1724
1722 __ mov(answer.reg(), left->reg()); 1725 __ mov(answer.reg(), left->reg());
1723 switch (op) { 1726 switch (op) {
1724 case Token::ADD: 1727 case Token::ADD:
1725 __ add(answer.reg(), Operand(right->reg())); 1728 __ add(answer.reg(), Operand(right->reg()));
1726 deferred->Branch(overflow); 1729 deferred->Branch(overflow);
1727 break; 1730 break;
1728 1731
1729 case Token::SUB: 1732 case Token::SUB:
1730 __ sub(answer.reg(), Operand(right->reg())); 1733 __ sub(answer.reg(), Operand(right->reg()));
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1981 GenericBinaryOpStub igostub( 1984 GenericBinaryOpStub igostub(
1982 Token::SUB, 1985 Token::SUB,
1983 overwrite_mode_, 1986 overwrite_mode_,
1984 NO_SMI_CODE_IN_STUB, 1987 NO_SMI_CODE_IN_STUB,
1985 TypeInfo::Combine(TypeInfo::Smi(), type_info_)); 1988 TypeInfo::Combine(TypeInfo::Smi(), type_info_));
1986 igostub.GenerateCall(masm_, dst_, value_); 1989 igostub.GenerateCall(masm_, dst_, value_);
1987 if (!dst_.is(eax)) __ mov(dst_, eax); 1990 if (!dst_.is(eax)) __ mov(dst_, eax);
1988 } 1991 }
1989 1992
1990 1993
1991 Result CodeGenerator::ConstantSmiBinaryOperation( 1994 Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr,
1992 BinaryOperation* expr, 1995 Result* operand,
1993 Result* operand, 1996 Handle<Object> value,
1994 Handle<Object> value, 1997 bool reversed,
1995 bool reversed, 1998 OverwriteMode overwrite_mode) {
1996 OverwriteMode overwrite_mode) { 1999 // Generate inline code for a binary operation when one of the
1997 // NOTE: This is an attempt to inline (a bit) more of the code for 2000 // operands is a constant smi. Consumes the argument "operand".
1998 // some possible smi operations (like + and -) when (at least) one
1999 // of the operands is a constant smi.
2000 // Consumes the argument "operand".
2001 // TODO(199): Optimize some special cases of operations involving a
2002 // smi literal (multiply by 2, shift by 0, etc.).
2003 if (IsUnsafeSmi(value)) { 2001 if (IsUnsafeSmi(value)) {
2004 Result unsafe_operand(value); 2002 Result unsafe_operand(value);
2005 if (reversed) { 2003 if (reversed) {
2006 return LikelySmiBinaryOperation(expr, &unsafe_operand, operand, 2004 return LikelySmiBinaryOperation(expr, &unsafe_operand, operand,
2007 overwrite_mode); 2005 overwrite_mode);
2008 } else { 2006 } else {
2009 return LikelySmiBinaryOperation(expr, operand, &unsafe_operand, 2007 return LikelySmiBinaryOperation(expr, operand, &unsafe_operand,
2010 overwrite_mode); 2008 overwrite_mode);
2011 } 2009 }
2012 } 2010 }
(...skipping 11104 matching lines...) Expand 10 before | Expand all | Expand 10 after
13117 13115
13118 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 13116 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
13119 // tagged as a small integer. 13117 // tagged as a small integer.
13120 __ bind(&runtime); 13118 __ bind(&runtime);
13121 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 13119 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
13122 } 13120 }
13123 13121
13124 #undef __ 13122 #undef __
13125 13123
13126 } } // namespace v8::internal 13124 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698