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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 131363008: A64: Synchronize with r15922. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 chunk_->LookupLiteralRepresentation(op).IsSmi(); 403 chunk_->LookupLiteralRepresentation(op).IsSmi();
404 } 404 }
405 405
406 406
407 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { 407 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const {
408 return op->IsConstantOperand() && 408 return op->IsConstantOperand() &&
409 chunk_->LookupLiteralRepresentation(op).IsTagged(); 409 chunk_->LookupLiteralRepresentation(op).IsTagged();
410 } 410 }
411 411
412 412
413 int LCodeGen::ToInteger32(LConstantOperand* op) const { 413 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
414 HConstant* constant = chunk_->LookupConstant(op); 414 HConstant* constant = chunk_->LookupConstant(op);
415 return constant->Integer32Value(); 415 return constant->Integer32Value();
416 } 416 }
417 417
418 418
419 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { 419 Smi* LCodeGen::ToSmi(LConstantOperand* op) const {
420 HConstant* constant = chunk_->LookupConstant(op); 420 HConstant* constant = chunk_->LookupConstant(op);
421 return Smi::FromInt(constant->Integer32Value()); 421 return Smi::FromInt(constant->Integer32Value());
422 } 422 }
423 423
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 690
691 void LCodeGen::DeoptimizeIf(Condition cc, 691 void LCodeGen::DeoptimizeIf(Condition cc,
692 LEnvironment* environment) { 692 LEnvironment* environment) {
693 Deoptimizer::BailoutType bailout_type = info()->IsStub() 693 Deoptimizer::BailoutType bailout_type = info()->IsStub()
694 ? Deoptimizer::LAZY 694 ? Deoptimizer::LAZY
695 : Deoptimizer::EAGER; 695 : Deoptimizer::EAGER;
696 DeoptimizeIf(cc, environment, bailout_type); 696 DeoptimizeIf(cc, environment, bailout_type);
697 } 697 }
698 698
699 699
700 void LCodeGen::SoftDeoptimize(LEnvironment* environment) {
701 ASSERT(!info()->IsStub());
702 DeoptimizeIf(no_condition, environment, Deoptimizer::SOFT);
703 }
704
705
706 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 700 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
707 ZoneList<Handle<Map> > maps(1, zone()); 701 ZoneList<Handle<Map> > maps(1, zone());
708 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 702 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
709 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 703 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
710 RelocInfo::Mode mode = it.rinfo()->rmode(); 704 RelocInfo::Mode mode = it.rinfo()->rmode();
711 if (mode == RelocInfo::EMBEDDED_OBJECT && 705 if (mode == RelocInfo::EMBEDDED_OBJECT &&
712 it.rinfo()->target_object()->IsMap()) { 706 it.rinfo()->target_object()->IsMap()) {
713 Handle<Map> map(Map::cast(it.rinfo()->target_object())); 707 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
714 if (map->CanTransition()) { 708 if (map->CanTransition()) {
715 maps.Add(map, zone()); 709 maps.Add(map, zone());
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 __ shll(left, Immediate(4)); 1292 __ shll(left, Immediate(4));
1299 break; 1293 break;
1300 default: 1294 default:
1301 __ imull(left, left, Immediate(right_value)); 1295 __ imull(left, left, Immediate(right_value));
1302 break; 1296 break;
1303 } 1297 }
1304 } else { 1298 } else {
1305 __ imull(left, left, Immediate(right_value)); 1299 __ imull(left, left, Immediate(right_value));
1306 } 1300 }
1307 } else if (right->IsStackSlot()) { 1301 } else if (right->IsStackSlot()) {
1308 __ imull(left, ToOperand(right)); 1302 if (instr->hydrogen_value()->representation().IsSmi()) {
1303 __ SmiToInteger32(left, left);
1304 __ imul(left, ToOperand(right));
1305 } else {
1306 __ imull(left, ToOperand(right));
1307 }
1309 } else { 1308 } else {
1310 __ imull(left, ToRegister(right)); 1309 if (instr->hydrogen_value()->representation().IsSmi()) {
1310 __ SmiToInteger32(left, left);
1311 __ imul(left, ToRegister(right));
1312 } else {
1313 __ imull(left, ToRegister(right));
1314 }
1311 } 1315 }
1312 1316
1313 if (can_overflow) { 1317 if (can_overflow) {
1314 DeoptimizeIf(overflow, instr->environment()); 1318 DeoptimizeIf(overflow, instr->environment());
1315 } 1319 }
1316 1320
1317 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1321 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1318 // Bail out if the result is supposed to be negative zero. 1322 // Bail out if the result is supposed to be negative zero.
1319 Label done; 1323 Label done;
1320 __ testl(left, left); 1324 __ testl(left, left);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 case Token::BIT_XOR: 1361 case Token::BIT_XOR:
1358 __ xorl(ToRegister(left), Immediate(right_operand)); 1362 __ xorl(ToRegister(left), Immediate(right_operand));
1359 break; 1363 break;
1360 default: 1364 default:
1361 UNREACHABLE(); 1365 UNREACHABLE();
1362 break; 1366 break;
1363 } 1367 }
1364 } else if (right->IsStackSlot()) { 1368 } else if (right->IsStackSlot()) {
1365 switch (instr->op()) { 1369 switch (instr->op()) {
1366 case Token::BIT_AND: 1370 case Token::BIT_AND:
1367 __ andl(ToRegister(left), ToOperand(right)); 1371 __ and_(ToRegister(left), ToOperand(right));
1368 break; 1372 break;
1369 case Token::BIT_OR: 1373 case Token::BIT_OR:
1370 __ orl(ToRegister(left), ToOperand(right)); 1374 __ or_(ToRegister(left), ToOperand(right));
1371 break; 1375 break;
1372 case Token::BIT_XOR: 1376 case Token::BIT_XOR:
1373 __ xorl(ToRegister(left), ToOperand(right)); 1377 __ xor_(ToRegister(left), ToOperand(right));
1374 break; 1378 break;
1375 default: 1379 default:
1376 UNREACHABLE(); 1380 UNREACHABLE();
1377 break; 1381 break;
1378 } 1382 }
1379 } else { 1383 } else {
1380 ASSERT(right->IsRegister()); 1384 ASSERT(right->IsRegister());
1381 switch (instr->op()) { 1385 switch (instr->op()) {
1382 case Token::BIT_AND: 1386 case Token::BIT_AND:
1383 __ andl(ToRegister(left), ToRegister(right)); 1387 __ and_(ToRegister(left), ToRegister(right));
1384 break; 1388 break;
1385 case Token::BIT_OR: 1389 case Token::BIT_OR:
1386 __ orl(ToRegister(left), ToRegister(right)); 1390 __ or_(ToRegister(left), ToRegister(right));
1387 break; 1391 break;
1388 case Token::BIT_XOR: 1392 case Token::BIT_XOR:
1389 __ xorl(ToRegister(left), ToRegister(right)); 1393 __ xor_(ToRegister(left), ToRegister(right));
1390 break; 1394 break;
1391 default: 1395 default:
1392 UNREACHABLE(); 1396 UNREACHABLE();
1393 break; 1397 break;
1394 } 1398 }
1395 } 1399 }
1396 } 1400 }
1397 1401
1398 1402
1399 void LCodeGen::DoShiftI(LShiftI* instr) { 1403 void LCodeGen::DoShiftI(LShiftI* instr) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 case Token::SHR: 1446 case Token::SHR:
1443 if (shift_count == 0 && instr->can_deopt()) { 1447 if (shift_count == 0 && instr->can_deopt()) {
1444 __ testl(ToRegister(left), ToRegister(left)); 1448 __ testl(ToRegister(left), ToRegister(left));
1445 DeoptimizeIf(negative, instr->environment()); 1449 DeoptimizeIf(negative, instr->environment());
1446 } else { 1450 } else {
1447 __ shrl(ToRegister(left), Immediate(shift_count)); 1451 __ shrl(ToRegister(left), Immediate(shift_count));
1448 } 1452 }
1449 break; 1453 break;
1450 case Token::SHL: 1454 case Token::SHL:
1451 if (shift_count != 0) { 1455 if (shift_count != 0) {
1452 __ shll(ToRegister(left), Immediate(shift_count)); 1456 if (instr->hydrogen_value()->representation().IsSmi()) {
1457 __ shl(ToRegister(left), Immediate(shift_count));
1458 } else {
1459 __ shll(ToRegister(left), Immediate(shift_count));
1460 }
1453 } 1461 }
1454 break; 1462 break;
1455 default: 1463 default:
1456 UNREACHABLE(); 1464 UNREACHABLE();
1457 break; 1465 break;
1458 } 1466 }
1459 } 1467 }
1460 } 1468 }
1461 1469
1462 1470
1463 void LCodeGen::DoSubI(LSubI* instr) { 1471 void LCodeGen::DoSubI(LSubI* instr) {
1464 LOperand* left = instr->left(); 1472 LOperand* left = instr->left();
1465 LOperand* right = instr->right(); 1473 LOperand* right = instr->right();
1466 ASSERT(left->Equals(instr->result())); 1474 ASSERT(left->Equals(instr->result()));
1467 1475
1468 if (right->IsConstantOperand()) { 1476 if (right->IsConstantOperand()) {
1469 __ subl(ToRegister(left), 1477 __ subl(ToRegister(left),
1470 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1478 Immediate(ToInteger32(LConstantOperand::cast(right))));
1471 } else if (right->IsRegister()) { 1479 } else if (right->IsRegister()) {
1472 __ subl(ToRegister(left), ToRegister(right)); 1480 if (instr->hydrogen_value()->representation().IsSmi()) {
1481 __ subq(ToRegister(left), ToRegister(right));
1482 } else {
1483 __ subl(ToRegister(left), ToRegister(right));
1484 }
1473 } else { 1485 } else {
1474 __ subl(ToRegister(left), ToOperand(right)); 1486 if (instr->hydrogen_value()->representation().IsSmi()) {
1487 __ subq(ToRegister(left), ToOperand(right));
1488 } else {
1489 __ subl(ToRegister(left), ToOperand(right));
1490 }
1475 } 1491 }
1476 1492
1477 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1493 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1478 DeoptimizeIf(overflow, instr->environment()); 1494 DeoptimizeIf(overflow, instr->environment());
1479 } 1495 }
1480 } 1496 }
1481 1497
1482 1498
1483 void LCodeGen::DoConstantI(LConstantI* instr) { 1499 void LCodeGen::DoConstantI(LConstantI* instr) {
1484 __ Set(ToRegister(instr->result()), instr->value()); 1500 __ Set(ToRegister(instr->result()), instr->value());
(...skipping 18 matching lines...) Expand all
1503 Register tmp = ToRegister(instr->temp()); 1519 Register tmp = ToRegister(instr->temp());
1504 __ Set(tmp, int_val); 1520 __ Set(tmp, int_val);
1505 __ movq(res, tmp); 1521 __ movq(res, tmp);
1506 } 1522 }
1507 } 1523 }
1508 1524
1509 1525
1510 void LCodeGen::DoConstantT(LConstantT* instr) { 1526 void LCodeGen::DoConstantT(LConstantT* instr) {
1511 Handle<Object> value = instr->value(); 1527 Handle<Object> value = instr->value();
1512 AllowDeferredHandleDereference smi_check; 1528 AllowDeferredHandleDereference smi_check;
1513 if (value->IsSmi()) { 1529 __ LoadObject(ToRegister(instr->result()), value);
1514 __ Move(ToRegister(instr->result()), value);
1515 } else {
1516 __ LoadHeapObject(ToRegister(instr->result()),
1517 Handle<HeapObject>::cast(value));
1518 }
1519 } 1530 }
1520 1531
1521 1532
1522 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { 1533 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
1523 Register result = ToRegister(instr->result()); 1534 Register result = ToRegister(instr->result());
1524 Register map = ToRegister(instr->value()); 1535 Register map = ToRegister(instr->value());
1525 __ EnumLength(result, map); 1536 __ EnumLength(result, map);
1526 } 1537 }
1527 1538
1528 1539
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 LOperand* left = instr->left(); 1661 LOperand* left = instr->left();
1651 LOperand* right = instr->right(); 1662 LOperand* right = instr->right();
1652 1663
1653 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { 1664 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) {
1654 if (right->IsConstantOperand()) { 1665 if (right->IsConstantOperand()) {
1655 int32_t offset = ToInteger32(LConstantOperand::cast(right)); 1666 int32_t offset = ToInteger32(LConstantOperand::cast(right));
1656 __ leal(ToRegister(instr->result()), 1667 __ leal(ToRegister(instr->result()),
1657 MemOperand(ToRegister(left), offset)); 1668 MemOperand(ToRegister(left), offset));
1658 } else { 1669 } else {
1659 Operand address(ToRegister(left), ToRegister(right), times_1, 0); 1670 Operand address(ToRegister(left), ToRegister(right), times_1, 0);
1660 __ leal(ToRegister(instr->result()), address); 1671 if (instr->hydrogen()->representation().IsSmi()) {
1672 __ lea(ToRegister(instr->result()), address);
1673 } else {
1674 __ leal(ToRegister(instr->result()), address);
1675 }
1661 } 1676 }
1662 } else { 1677 } else {
1663 if (right->IsConstantOperand()) { 1678 if (right->IsConstantOperand()) {
1664 __ addl(ToRegister(left), 1679 __ addl(ToRegister(left),
1665 Immediate(ToInteger32(LConstantOperand::cast(right)))); 1680 Immediate(ToInteger32(LConstantOperand::cast(right))));
1666 } else if (right->IsRegister()) { 1681 } else if (right->IsRegister()) {
1667 __ addl(ToRegister(left), ToRegister(right)); 1682 if (instr->hydrogen_value()->representation().IsSmi()) {
1683 __ addq(ToRegister(left), ToRegister(right));
1684 } else {
1685 __ addl(ToRegister(left), ToRegister(right));
1686 }
1668 } else { 1687 } else {
1669 __ addl(ToRegister(left), ToOperand(right)); 1688 if (instr->hydrogen_value()->representation().IsSmi()) {
1689 __ addq(ToRegister(left), ToOperand(right));
1690 } else {
1691 __ addl(ToRegister(left), ToOperand(right));
1692 }
1670 } 1693 }
1671 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { 1694 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
1672 DeoptimizeIf(overflow, instr->environment()); 1695 DeoptimizeIf(overflow, instr->environment());
1673 } 1696 }
1674 } 1697 }
1675 } 1698 }
1676 1699
1677 1700
1678 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { 1701 void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
1679 LOperand* left = instr->left(); 1702 LOperand* left = instr->left();
1680 LOperand* right = instr->right(); 1703 LOperand* right = instr->right();
1681 ASSERT(left->Equals(instr->result())); 1704 ASSERT(left->Equals(instr->result()));
1682 HMathMinMax::Operation operation = instr->hydrogen()->operation(); 1705 HMathMinMax::Operation operation = instr->hydrogen()->operation();
1683 if (instr->hydrogen()->representation().IsInteger32()) { 1706 if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
1684 Label return_left; 1707 Label return_left;
1685 Condition condition = (operation == HMathMinMax::kMathMin) 1708 Condition condition = (operation == HMathMinMax::kMathMin)
1686 ? less_equal 1709 ? less_equal
1687 : greater_equal; 1710 : greater_equal;
1688 Register left_reg = ToRegister(left); 1711 Register left_reg = ToRegister(left);
1689 if (right->IsConstantOperand()) { 1712 if (right->IsConstantOperand()) {
1690 Immediate right_imm = 1713 Immediate right_imm =
1691 Immediate(ToInteger32(LConstantOperand::cast(right))); 1714 Immediate(ToInteger32(LConstantOperand::cast(right)));
1715 ASSERT(!instr->hydrogen_value()->representation().IsSmi());
1692 __ cmpl(left_reg, right_imm); 1716 __ cmpl(left_reg, right_imm);
1693 __ j(condition, &return_left, Label::kNear); 1717 __ j(condition, &return_left, Label::kNear);
1694 __ movq(left_reg, right_imm); 1718 __ movq(left_reg, right_imm);
1695 } else if (right->IsRegister()) { 1719 } else if (right->IsRegister()) {
1696 Register right_reg = ToRegister(right); 1720 Register right_reg = ToRegister(right);
1697 __ cmpl(left_reg, right_reg); 1721 if (instr->hydrogen_value()->representation().IsSmi()) {
1722 __ cmpq(left_reg, right_reg);
1723 } else {
1724 __ cmpl(left_reg, right_reg);
1725 }
1698 __ j(condition, &return_left, Label::kNear); 1726 __ j(condition, &return_left, Label::kNear);
1699 __ movq(left_reg, right_reg); 1727 __ movq(left_reg, right_reg);
1700 } else { 1728 } else {
1701 Operand right_op = ToOperand(right); 1729 Operand right_op = ToOperand(right);
1702 __ cmpl(left_reg, right_op); 1730 if (instr->hydrogen_value()->representation().IsSmi()) {
1731 __ cmpq(left_reg, right_op);
1732 } else {
1733 __ cmpl(left_reg, right_op);
1734 }
1703 __ j(condition, &return_left, Label::kNear); 1735 __ j(condition, &return_left, Label::kNear);
1704 __ movq(left_reg, right_op); 1736 __ movq(left_reg, right_op);
1705 } 1737 }
1706 __ bind(&return_left); 1738 __ bind(&return_left);
1707 } else { 1739 } else {
1708 ASSERT(instr->hydrogen()->representation().IsDouble()); 1740 ASSERT(instr->hydrogen()->representation().IsDouble());
1709 Label check_nan_left, check_zero, return_left, return_right; 1741 Label check_nan_left, check_zero, return_left, return_right;
1710 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; 1742 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above;
1711 XMMRegister left_reg = ToDoubleRegister(left); 1743 XMMRegister left_reg = ToDoubleRegister(left);
1712 XMMRegister right_reg = ToDoubleRegister(right); 1744 XMMRegister right_reg = ToDoubleRegister(right);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); 2112 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
2081 __ CmpObject(left, right); 2113 __ CmpObject(left, right);
2082 } else { 2114 } else {
2083 Register right = ToRegister(instr->right()); 2115 Register right = ToRegister(instr->right());
2084 __ cmpq(left, right); 2116 __ cmpq(left, right);
2085 } 2117 }
2086 EmitBranch(instr, equal); 2118 EmitBranch(instr, equal);
2087 } 2119 }
2088 2120
2089 2121
2090 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
2091 Register left = ToRegister(instr->left());
2092
2093 __ cmpq(left, Immediate(instr->hydrogen()->right()));
2094 EmitBranch(instr, equal);
2095 }
2096
2097
2098 Condition LCodeGen::EmitIsObject(Register input, 2122 Condition LCodeGen::EmitIsObject(Register input,
2099 Label* is_not_object, 2123 Label* is_not_object,
2100 Label* is_object) { 2124 Label* is_object) {
2101 ASSERT(!input.is(kScratchRegister)); 2125 ASSERT(!input.is(kScratchRegister));
2102 2126
2103 __ JumpIfSmi(input, is_not_object); 2127 __ JumpIfSmi(input, is_not_object);
2104 2128
2105 __ CompareRoot(input, Heap::kNullValueRootIndex); 2129 __ CompareRoot(input, Heap::kNullValueRootIndex);
2106 __ j(equal, is_object); 2130 __ j(equal, is_object);
2107 2131
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
2696 int offset = index * kPointerSize; 2720 int offset = index * kPointerSize;
2697 if (index < 0) { 2721 if (index < 0) {
2698 // Negative property indices are in-object properties, indexed 2722 // Negative property indices are in-object properties, indexed
2699 // from the end of the fixed part of the object. 2723 // from the end of the fixed part of the object.
2700 __ movq(result, FieldOperand(object, offset + type->instance_size())); 2724 __ movq(result, FieldOperand(object, offset + type->instance_size()));
2701 } else { 2725 } else {
2702 // Non-negative property indices are in the properties array. 2726 // Non-negative property indices are in the properties array.
2703 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2727 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2704 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); 2728 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
2705 } 2729 }
2706 } else if (lookup.IsConstantFunction()) { 2730 } else if (lookup.IsConstant()) {
2707 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); 2731 Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
2708 __ LoadHeapObject(result, function); 2732 __ LoadObject(result, constant);
2709 } else { 2733 } else {
2710 // Negative lookup. 2734 // Negative lookup.
2711 // Check prototypes. 2735 // Check prototypes.
2712 Handle<HeapObject> current(HeapObject::cast((*type)->prototype())); 2736 Handle<HeapObject> current(HeapObject::cast((*type)->prototype()));
2713 Heap* heap = type->GetHeap(); 2737 Heap* heap = type->GetHeap();
2714 while (*current != heap->null_value()) { 2738 while (*current != heap->null_value()) {
2715 __ LoadHeapObject(result, current); 2739 __ LoadHeapObject(result, current);
2716 __ Cmp(FieldOperand(result, HeapObject::kMapOffset), 2740 __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
2717 Handle<Map>(current->map())); 2741 Handle<Map>(current->map()));
2718 DeoptimizeIf(not_equal, env); 2742 DeoptimizeIf(not_equal, env);
(...skipping 10 matching lines...) Expand all
2729 static bool CompactEmit(SmallMapList* list, 2753 static bool CompactEmit(SmallMapList* list,
2730 Handle<String> name, 2754 Handle<String> name,
2731 int i, 2755 int i,
2732 Isolate* isolate) { 2756 Isolate* isolate) {
2733 Handle<Map> map = list->at(i); 2757 Handle<Map> map = list->at(i);
2734 // If the map has ElementsKind transitions, we will generate map checks 2758 // If the map has ElementsKind transitions, we will generate map checks
2735 // for each kind in __ CompareMap(..., ALLOW_ELEMENTS_TRANSITION_MAPS). 2759 // for each kind in __ CompareMap(..., ALLOW_ELEMENTS_TRANSITION_MAPS).
2736 if (map->HasElementsTransition()) return false; 2760 if (map->HasElementsTransition()) return false;
2737 LookupResult lookup(isolate); 2761 LookupResult lookup(isolate);
2738 map->LookupDescriptor(NULL, *name, &lookup); 2762 map->LookupDescriptor(NULL, *name, &lookup);
2739 return lookup.IsField() || lookup.IsConstantFunction(); 2763 return lookup.IsField() || lookup.IsConstant();
2740 } 2764 }
2741 2765
2742 2766
2743 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { 2767 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2744 Register object = ToRegister(instr->object()); 2768 Register object = ToRegister(instr->object());
2745 Register result = ToRegister(instr->result()); 2769 Register result = ToRegister(instr->result());
2746 2770
2747 int map_count = instr->hydrogen()->types()->length(); 2771 int map_count = instr->hydrogen()->types()->length();
2748 bool need_generic = instr->hydrogen()->need_generic(); 2772 bool need_generic = instr->hydrogen()->need_generic();
2749 2773
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2879 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 2903 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2880 ElementsKind elements_kind = instr->elements_kind(); 2904 ElementsKind elements_kind = instr->elements_kind();
2881 LOperand* key = instr->key(); 2905 LOperand* key = instr->key();
2882 if (!key->IsConstantOperand()) { 2906 if (!key->IsConstantOperand()) {
2883 Register key_reg = ToRegister(key); 2907 Register key_reg = ToRegister(key);
2884 // Even though the HLoad/StoreKeyed (in this case) instructions force 2908 // Even though the HLoad/StoreKeyed (in this case) instructions force
2885 // the input representation for the key to be an integer, the input 2909 // the input representation for the key to be an integer, the input
2886 // gets replaced during bound check elimination with the index argument 2910 // gets replaced during bound check elimination with the index argument
2887 // to the bounds check, which can be tagged, so that case must be 2911 // to the bounds check, which can be tagged, so that case must be
2888 // handled here, too. 2912 // handled here, too.
2889 if (instr->hydrogen()->key()->representation().IsSmi()) { 2913 if (instr->hydrogen()->IsDehoisted()) {
2890 __ SmiToInteger64(key_reg, key_reg);
2891 } else if (instr->hydrogen()->IsDehoisted()) {
2892 // Sign extend key because it could be a 32 bit negative value 2914 // Sign extend key because it could be a 32 bit negative value
2893 // and the dehoisted address computation happens in 64 bits 2915 // and the dehoisted address computation happens in 64 bits
2894 __ movsxlq(key_reg, key_reg); 2916 __ movsxlq(key_reg, key_reg);
2895 } 2917 }
2896 } 2918 }
2897 Operand operand(BuildFastArrayOperand( 2919 Operand operand(BuildFastArrayOperand(
2898 instr->elements(), 2920 instr->elements(),
2899 key, 2921 key,
2900 elements_kind, 2922 elements_kind,
2901 0, 2923 0,
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 2974
2953 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 2975 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2954 XMMRegister result(ToDoubleRegister(instr->result())); 2976 XMMRegister result(ToDoubleRegister(instr->result()));
2955 LOperand* key = instr->key(); 2977 LOperand* key = instr->key();
2956 if (!key->IsConstantOperand()) { 2978 if (!key->IsConstantOperand()) {
2957 Register key_reg = ToRegister(key); 2979 Register key_reg = ToRegister(key);
2958 // Even though the HLoad/StoreKeyed instructions force the input 2980 // Even though the HLoad/StoreKeyed instructions force the input
2959 // representation for the key to be an integer, the input gets replaced 2981 // representation for the key to be an integer, the input gets replaced
2960 // during bound check elimination with the index argument to the bounds 2982 // during bound check elimination with the index argument to the bounds
2961 // check, which can be tagged, so that case must be handled here, too. 2983 // check, which can be tagged, so that case must be handled here, too.
2962 if (instr->hydrogen()->key()->representation().IsSmi()) { 2984 if (instr->hydrogen()->IsDehoisted()) {
2963 __ SmiToInteger64(key_reg, key_reg);
2964 } else if (instr->hydrogen()->IsDehoisted()) {
2965 // Sign extend key because it could be a 32 bit negative value 2985 // Sign extend key because it could be a 32 bit negative value
2966 // and the dehoisted address computation happens in 64 bits 2986 // and the dehoisted address computation happens in 64 bits
2967 __ movsxlq(key_reg, key_reg); 2987 __ movsxlq(key_reg, key_reg);
2968 } 2988 }
2969 } 2989 }
2970 2990
2971 if (instr->hydrogen()->RequiresHoleCheck()) { 2991 if (instr->hydrogen()->RequiresHoleCheck()) {
2972 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2992 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2973 sizeof(kHoleNanLower32); 2993 sizeof(kHoleNanLower32);
2974 Operand hole_check_operand = BuildFastArrayOperand( 2994 Operand hole_check_operand = BuildFastArrayOperand(
(...skipping 19 matching lines...) Expand all
2994 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3014 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
2995 Register result = ToRegister(instr->result()); 3015 Register result = ToRegister(instr->result());
2996 LOperand* key = instr->key(); 3016 LOperand* key = instr->key();
2997 if (!key->IsConstantOperand()) { 3017 if (!key->IsConstantOperand()) {
2998 Register key_reg = ToRegister(key); 3018 Register key_reg = ToRegister(key);
2999 // Even though the HLoad/StoreKeyedFastElement instructions force 3019 // Even though the HLoad/StoreKeyedFastElement instructions force
3000 // the input representation for the key to be an integer, the input 3020 // the input representation for the key to be an integer, the input
3001 // gets replaced during bound check elimination with the index 3021 // gets replaced during bound check elimination with the index
3002 // argument to the bounds check, which can be tagged, so that 3022 // argument to the bounds check, which can be tagged, so that
3003 // case must be handled here, too. 3023 // case must be handled here, too.
3004 if (instr->hydrogen()->key()->representation().IsSmi()) { 3024 if (instr->hydrogen()->IsDehoisted()) {
3005 __ SmiToInteger64(key_reg, key_reg);
3006 } else if (instr->hydrogen()->IsDehoisted()) {
3007 // Sign extend key because it could be a 32 bit negative value 3025 // Sign extend key because it could be a 32 bit negative value
3008 // and the dehoisted address computation happens in 64 bits 3026 // and the dehoisted address computation happens in 64 bits
3009 __ movsxlq(key_reg, key_reg); 3027 __ movsxlq(key_reg, key_reg);
3010 } 3028 }
3011 } 3029 }
3012 3030
3013 // Load the result. 3031 // Load the result.
3014 __ movq(result, 3032 __ movq(result,
3015 BuildFastArrayOperand(instr->elements(), 3033 BuildFastArrayOperand(instr->elements(),
3016 key, 3034 key,
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
3336 RDI_UNINITIALIZED); 3354 RDI_UNINITIALIZED);
3337 } 3355 }
3338 3356
3339 3357
3340 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3358 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3341 Register input_reg = ToRegister(instr->value()); 3359 Register input_reg = ToRegister(instr->value());
3342 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3360 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
3343 Heap::kHeapNumberMapRootIndex); 3361 Heap::kHeapNumberMapRootIndex);
3344 DeoptimizeIf(not_equal, instr->environment()); 3362 DeoptimizeIf(not_equal, instr->environment());
3345 3363
3346 Label done; 3364 Label slow, allocated, done;
3347 Register tmp = input_reg.is(rax) ? rcx : rax; 3365 Register tmp = input_reg.is(rax) ? rcx : rax;
3348 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 3366 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
3349 3367
3350 // Preserve the value of all registers. 3368 // Preserve the value of all registers.
3351 PushSafepointRegistersScope scope(this); 3369 PushSafepointRegistersScope scope(this);
3352 3370
3353 Label negative;
3354 __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 3371 __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset));
3355 // Check the sign of the argument. If the argument is positive, just 3372 // Check the sign of the argument. If the argument is positive, just
3356 // return it. We do not need to patch the stack since |input| and 3373 // return it. We do not need to patch the stack since |input| and
3357 // |result| are the same register and |input| will be restored 3374 // |result| are the same register and |input| will be restored
3358 // unchanged by popping safepoint registers. 3375 // unchanged by popping safepoint registers.
3359 __ testl(tmp, Immediate(HeapNumber::kSignMask)); 3376 __ testl(tmp, Immediate(HeapNumber::kSignMask));
3360 __ j(not_zero, &negative); 3377 __ j(zero, &done);
3361 __ jmp(&done);
3362 3378
3363 __ bind(&negative);
3364
3365 Label allocated, slow;
3366 __ AllocateHeapNumber(tmp, tmp2, &slow); 3379 __ AllocateHeapNumber(tmp, tmp2, &slow);
3367 __ jmp(&allocated); 3380 __ jmp(&allocated, Label::kNear);
3368 3381
3369 // Slow case: Call the runtime system to do the number allocation. 3382 // Slow case: Call the runtime system to do the number allocation.
3370 __ bind(&slow); 3383 __ bind(&slow);
3371
3372 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 3384 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
3373 // Set the pointer to the new heap number in tmp. 3385 // Set the pointer to the new heap number in tmp.
3374 if (!tmp.is(rax)) { 3386 if (!tmp.is(rax)) __ movq(tmp, rax);
3375 __ movq(tmp, rax);
3376 }
3377
3378 // Restore input_reg after call to runtime. 3387 // Restore input_reg after call to runtime.
3379 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 3388 __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
3380 3389
3381 __ bind(&allocated); 3390 __ bind(&allocated);
3382 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3391 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
3383 __ shl(tmp2, Immediate(1)); 3392 __ shl(tmp2, Immediate(1));
3384 __ shr(tmp2, Immediate(1)); 3393 __ shr(tmp2, Immediate(1));
3385 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 3394 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
3386 __ StoreToSafepointRegisterSlot(input_reg, tmp); 3395 __ StoreToSafepointRegisterSlot(input_reg, tmp);
3387 3396
3388 __ bind(&done); 3397 __ bind(&done);
3389 } 3398 }
3390 3399
3391 3400
3392 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { 3401 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3393 Register input_reg = ToRegister(instr->value()); 3402 Register input_reg = ToRegister(instr->value());
3394 __ testl(input_reg, input_reg); 3403 __ testl(input_reg, input_reg);
3395 Label is_positive; 3404 Label is_positive;
3396 __ j(not_sign, &is_positive); 3405 __ j(not_sign, &is_positive, Label::kNear);
3397 __ negl(input_reg); // Sets flags. 3406 __ negl(input_reg); // Sets flags.
3398 DeoptimizeIf(negative, instr->environment()); 3407 DeoptimizeIf(negative, instr->environment());
3399 __ bind(&is_positive); 3408 __ bind(&is_positive);
3400 } 3409 }
3401 3410
3402 3411
3403 void LCodeGen::DoMathAbs(LMathAbs* instr) { 3412 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3404 // Class for deferred case. 3413 // Class for deferred case.
3405 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3414 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3406 public: 3415 public:
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
4016 ASSERT(ToRegister(instr->value()).is(rax)); 4025 ASSERT(ToRegister(instr->value()).is(rax));
4017 4026
4018 __ Move(rcx, instr->hydrogen()->name()); 4027 __ Move(rcx, instr->hydrogen()->name());
4019 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4028 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
4020 ? isolate()->builtins()->StoreIC_Initialize_Strict() 4029 ? isolate()->builtins()->StoreIC_Initialize_Strict()
4021 : isolate()->builtins()->StoreIC_Initialize(); 4030 : isolate()->builtins()->StoreIC_Initialize();
4022 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4031 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4023 } 4032 }
4024 4033
4025 4034
4035 void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
4036 if (FLAG_debug_code && check->hydrogen()->skip_check()) {
4037 Label done;
4038 __ j(NegateCondition(cc), &done, Label::kNear);
4039 __ int3();
4040 __ bind(&done);
4041 } else {
4042 DeoptimizeIf(cc, check->environment());
4043 }
4044 }
4045
4046
4026 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 4047 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
4027 if (instr->hydrogen()->skip_check()) return; 4048 if (instr->hydrogen()->skip_check()) return;
4028 4049
4029 if (instr->length()->IsRegister()) { 4050 if (instr->length()->IsRegister()) {
4030 Register reg = ToRegister(instr->length()); 4051 Register reg = ToRegister(instr->length());
4031 if (!instr->hydrogen()->length()->representation().IsSmi()) { 4052 if (!instr->hydrogen()->length()->representation().IsSmi()) {
4032 __ AssertZeroExtended(reg); 4053 __ AssertZeroExtended(reg);
4033 } 4054 }
4034 if (instr->index()->IsConstantOperand()) { 4055 if (instr->index()->IsConstantOperand()) {
4035 int constant_index = 4056 int constant_index =
(...skipping 17 matching lines...) Expand all
4053 ToInteger32(LConstantOperand::cast(instr->index())); 4074 ToInteger32(LConstantOperand::cast(instr->index()));
4054 if (instr->hydrogen()->length()->representation().IsSmi()) { 4075 if (instr->hydrogen()->length()->representation().IsSmi()) {
4055 __ Cmp(length, Smi::FromInt(constant_index)); 4076 __ Cmp(length, Smi::FromInt(constant_index));
4056 } else { 4077 } else {
4057 __ cmpq(length, Immediate(constant_index)); 4078 __ cmpq(length, Immediate(constant_index));
4058 } 4079 }
4059 } else { 4080 } else {
4060 __ cmpq(length, ToRegister(instr->index())); 4081 __ cmpq(length, ToRegister(instr->index()));
4061 } 4082 }
4062 } 4083 }
4063 DeoptimizeIf(below_equal, instr->environment()); 4084 Condition condition =
4085 instr->hydrogen()->allow_equality() ? below : below_equal;
4086 ApplyCheckIf(condition, instr);
4064 } 4087 }
4065 4088
4066 4089
4067 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4090 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4068 ElementsKind elements_kind = instr->elements_kind(); 4091 ElementsKind elements_kind = instr->elements_kind();
4069 LOperand* key = instr->key(); 4092 LOperand* key = instr->key();
4070 if (!key->IsConstantOperand()) { 4093 if (!key->IsConstantOperand()) {
4071 Register key_reg = ToRegister(key); 4094 Register key_reg = ToRegister(key);
4072 // Even though the HLoad/StoreKeyedFastElement instructions force 4095 // Even though the HLoad/StoreKeyedFastElement instructions force
4073 // the input representation for the key to be an integer, the input 4096 // the input representation for the key to be an integer, the input
4074 // gets replaced during bound check elimination with the index 4097 // gets replaced during bound check elimination with the index
4075 // argument to the bounds check, which can be tagged, so that case 4098 // argument to the bounds check, which can be tagged, so that case
4076 // must be handled here, too. 4099 // must be handled here, too.
4077 if (instr->hydrogen()->key()->representation().IsSmi()) { 4100 if (instr->hydrogen()->IsDehoisted()) {
4078 __ SmiToInteger64(key_reg, key_reg);
4079 } else if (instr->hydrogen()->IsDehoisted()) {
4080 // Sign extend key because it could be a 32 bit negative value 4101 // Sign extend key because it could be a 32 bit negative value
4081 // and the dehoisted address computation happens in 64 bits 4102 // and the dehoisted address computation happens in 64 bits
4082 __ movsxlq(key_reg, key_reg); 4103 __ movsxlq(key_reg, key_reg);
4083 } 4104 }
4084 } 4105 }
4085 Operand operand(BuildFastArrayOperand( 4106 Operand operand(BuildFastArrayOperand(
4086 instr->elements(), 4107 instr->elements(),
4087 key, 4108 key,
4088 elements_kind, 4109 elements_kind,
4089 0, 4110 0,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4131 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4152 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4132 XMMRegister value = ToDoubleRegister(instr->value()); 4153 XMMRegister value = ToDoubleRegister(instr->value());
4133 LOperand* key = instr->key(); 4154 LOperand* key = instr->key();
4134 if (!key->IsConstantOperand()) { 4155 if (!key->IsConstantOperand()) {
4135 Register key_reg = ToRegister(key); 4156 Register key_reg = ToRegister(key);
4136 // Even though the HLoad/StoreKeyedFastElement instructions force 4157 // Even though the HLoad/StoreKeyedFastElement instructions force
4137 // the input representation for the key to be an integer, the 4158 // the input representation for the key to be an integer, the
4138 // input gets replaced during bound check elimination with the index 4159 // input gets replaced during bound check elimination with the index
4139 // argument to the bounds check, which can be tagged, so that case 4160 // argument to the bounds check, which can be tagged, so that case
4140 // must be handled here, too. 4161 // must be handled here, too.
4141 if (instr->hydrogen()->key()->representation().IsSmi()) { 4162 if (instr->hydrogen()->IsDehoisted()) {
4142 __ SmiToInteger64(key_reg, key_reg);
4143 } else if (instr->hydrogen()->IsDehoisted()) {
4144 // Sign extend key because it could be a 32 bit negative value 4163 // Sign extend key because it could be a 32 bit negative value
4145 // and the dehoisted address computation happens in 64 bits 4164 // and the dehoisted address computation happens in 64 bits
4146 __ movsxlq(key_reg, key_reg); 4165 __ movsxlq(key_reg, key_reg);
4147 } 4166 }
4148 } 4167 }
4149 4168
4150 if (instr->NeedsCanonicalization()) { 4169 if (instr->NeedsCanonicalization()) {
4151 Label have_value; 4170 Label have_value;
4152 4171
4153 __ ucomisd(value, value); 4172 __ ucomisd(value, value);
(...skipping 20 matching lines...) Expand all
4174 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4193 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4175 Register elements = ToRegister(instr->elements()); 4194 Register elements = ToRegister(instr->elements());
4176 LOperand* key = instr->key(); 4195 LOperand* key = instr->key();
4177 if (!key->IsConstantOperand()) { 4196 if (!key->IsConstantOperand()) {
4178 Register key_reg = ToRegister(key); 4197 Register key_reg = ToRegister(key);
4179 // Even though the HLoad/StoreKeyedFastElement instructions force 4198 // Even though the HLoad/StoreKeyedFastElement instructions force
4180 // the input representation for the key to be an integer, the 4199 // the input representation for the key to be an integer, the
4181 // input gets replaced during bound check elimination with the index 4200 // input gets replaced during bound check elimination with the index
4182 // argument to the bounds check, which can be tagged, so that case 4201 // argument to the bounds check, which can be tagged, so that case
4183 // must be handled here, too. 4202 // must be handled here, too.
4184 if (instr->hydrogen()->key()->representation().IsSmi()) { 4203 if (instr->hydrogen()->IsDehoisted()) {
4185 __ SmiToInteger64(key_reg, key_reg);
4186 } else if (instr->hydrogen()->IsDehoisted()) {
4187 // Sign extend key because it could be a 32 bit negative value 4204 // Sign extend key because it could be a 32 bit negative value
4188 // and the dehoisted address computation happens in 64 bits 4205 // and the dehoisted address computation happens in 64 bits
4189 __ movsxlq(key_reg, key_reg); 4206 __ movsxlq(key_reg, key_reg);
4190 } 4207 }
4191 } 4208 }
4192 4209
4193 Operand operand = 4210 Operand operand =
4194 BuildFastArrayOperand(instr->elements(), 4211 BuildFastArrayOperand(instr->elements(),
4195 key, 4212 key,
4196 FAST_ELEMENTS, 4213 FAST_ELEMENTS,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4264 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 4281 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
4265 __ j(not_equal, &not_applicable); 4282 __ j(not_equal, &not_applicable);
4266 if (IsSimpleMapChangeTransition(from_kind, to_kind)) { 4283 if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
4267 Register new_map_reg = ToRegister(instr->new_map_temp()); 4284 Register new_map_reg = ToRegister(instr->new_map_temp());
4268 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); 4285 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT);
4269 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 4286 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
4270 // Write barrier. 4287 // Write barrier.
4271 ASSERT_NE(instr->temp(), NULL); 4288 ASSERT_NE(instr->temp(), NULL);
4272 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 4289 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
4273 ToRegister(instr->temp()), kDontSaveFPRegs); 4290 ToRegister(instr->temp()), kDontSaveFPRegs);
4274 } else if (FLAG_compiled_transitions) { 4291 } else {
4275 PushSafepointRegistersScope scope(this); 4292 PushSafepointRegistersScope scope(this);
4276 if (!object_reg.is(rax)) { 4293 if (!object_reg.is(rax)) {
4277 __ movq(rax, object_reg); 4294 __ movq(rax, object_reg);
4278 } 4295 }
4279 __ Move(rbx, to_map); 4296 __ Move(rbx, to_map);
4280 TransitionElementsKindStub stub(from_kind, to_kind); 4297 TransitionElementsKindStub stub(from_kind, to_kind);
4281 __ CallStub(&stub); 4298 __ CallStub(&stub);
4282 RecordSafepointWithRegisters( 4299 RecordSafepointWithRegisters(
4283 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 4300 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
4284 } else if (IsFastSmiElementsKind(from_kind) &&
4285 IsFastDoubleElementsKind(to_kind)) {
4286 Register fixed_object_reg = ToRegister(instr->temp());
4287 ASSERT(fixed_object_reg.is(rdx));
4288 Register new_map_reg = ToRegister(instr->new_map_temp());
4289 ASSERT(new_map_reg.is(rbx));
4290 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT);
4291 __ movq(fixed_object_reg, object_reg);
4292 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
4293 RelocInfo::CODE_TARGET, instr);
4294 } else if (IsFastDoubleElementsKind(from_kind) &&
4295 IsFastObjectElementsKind(to_kind)) {
4296 Register fixed_object_reg = ToRegister(instr->temp());
4297 ASSERT(fixed_object_reg.is(rdx));
4298 Register new_map_reg = ToRegister(instr->new_map_temp());
4299 ASSERT(new_map_reg.is(rbx));
4300 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT);
4301 __ movq(fixed_object_reg, object_reg);
4302 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
4303 RelocInfo::CODE_TARGET, instr);
4304 } else {
4305 UNREACHABLE();
4306 } 4301 }
4307 __ bind(&not_applicable); 4302 __ bind(&not_applicable);
4308 } 4303 }
4309 4304
4310 4305
4311 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { 4306 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
4312 Register object = ToRegister(instr->object()); 4307 Register object = ToRegister(instr->object());
4313 Register temp = ToRegister(instr->temp()); 4308 Register temp = ToRegister(instr->temp());
4314 __ TestJSArrayForAllocationMemento(object, temp); 4309 __ TestJSArrayForAllocationMemento(object, temp);
4315 DeoptimizeIf(equal, instr->environment()); 4310 DeoptimizeIf(equal, instr->environment());
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
4947 Handle<Map> map, 4942 Handle<Map> map,
4948 LInstruction* instr) { 4943 LInstruction* instr) {
4949 Label success; 4944 Label success;
4950 __ CompareMap(reg, map, &success); 4945 __ CompareMap(reg, map, &success);
4951 DeoptimizeIf(not_equal, instr->environment()); 4946 DeoptimizeIf(not_equal, instr->environment());
4952 __ bind(&success); 4947 __ bind(&success);
4953 } 4948 }
4954 4949
4955 4950
4956 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 4951 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
4952 if (instr->hydrogen()->CanOmitMapChecks()) return;
4957 LOperand* input = instr->value(); 4953 LOperand* input = instr->value();
4958 ASSERT(input->IsRegister()); 4954 ASSERT(input->IsRegister());
4959 Register reg = ToRegister(input); 4955 Register reg = ToRegister(input);
4960 4956
4961 Label success; 4957 Label success;
4962 SmallMapList* map_set = instr->hydrogen()->map_set(); 4958 SmallMapList* map_set = instr->hydrogen()->map_set();
4963 for (int i = 0; i < map_set->length() - 1; i++) { 4959 for (int i = 0; i < map_set->length() - 1; i++) {
4964 Handle<Map> map = map_set->at(i); 4960 Handle<Map> map = map_set->at(i);
4965 __ CompareMap(reg, map, &success); 4961 __ CompareMap(reg, map, &success);
4966 __ j(equal, &success); 4962 __ j(equal, &success);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
5014 // smi 5010 // smi
5015 __ bind(&is_smi); 5011 __ bind(&is_smi);
5016 __ SmiToInteger32(input_reg, input_reg); 5012 __ SmiToInteger32(input_reg, input_reg);
5017 __ ClampUint8(input_reg); 5013 __ ClampUint8(input_reg);
5018 5014
5019 __ bind(&done); 5015 __ bind(&done);
5020 } 5016 }
5021 5017
5022 5018
5023 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { 5019 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
5020 if (instr->hydrogen()->CanOmitPrototypeChecks()) return;
5024 Register reg = ToRegister(instr->temp()); 5021 Register reg = ToRegister(instr->temp());
5025 5022
5026 ZoneList<Handle<JSObject> >* prototypes = instr->prototypes(); 5023 ZoneList<Handle<JSObject> >* prototypes = instr->prototypes();
5027 ZoneList<Handle<Map> >* maps = instr->maps(); 5024 ZoneList<Handle<Map> >* maps = instr->maps();
5028 5025
5029 ASSERT(prototypes->length() == maps->length()); 5026 ASSERT(prototypes->length() == maps->length());
5030 5027
5031 if (!instr->hydrogen()->CanOmitPrototypeChecks()) { 5028 for (int i = 0; i < prototypes->length(); i++) {
5032 for (int i = 0; i < prototypes->length(); i++) { 5029 __ LoadHeapObject(reg, prototypes->at(i));
5033 __ LoadHeapObject(reg, prototypes->at(i)); 5030 DoCheckMapCommon(reg, maps->at(i), instr);
5034 DoCheckMapCommon(reg, maps->at(i), instr);
5035 }
5036 } 5031 }
5037 } 5032 }
5038 5033
5039 5034
5040 void LCodeGen::DoAllocate(LAllocate* instr) { 5035 void LCodeGen::DoAllocate(LAllocate* instr) {
5041 class DeferredAllocate: public LDeferredCode { 5036 class DeferredAllocate: public LDeferredCode {
5042 public: 5037 public:
5043 DeferredAllocate(LCodeGen* codegen, LAllocate* instr) 5038 DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
5044 : LDeferredCode(codegen), instr_(instr) { } 5039 : LDeferredCode(codegen), instr_(instr) { }
5045 virtual void Generate() { codegen()->DoDeferredAllocate(instr_); } 5040 virtual void Generate() { codegen()->DoDeferredAllocate(instr_); }
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
5357 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 5352 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
5358 last_lazy_deopt_pc_ = masm()->pc_offset(); 5353 last_lazy_deopt_pc_ = masm()->pc_offset();
5359 ASSERT(instr->HasEnvironment()); 5354 ASSERT(instr->HasEnvironment());
5360 LEnvironment* env = instr->environment(); 5355 LEnvironment* env = instr->environment();
5361 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 5356 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
5362 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5357 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5363 } 5358 }
5364 5359
5365 5360
5366 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5361 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5367 if (instr->hydrogen_value()->IsSoftDeoptimize()) { 5362 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5368 SoftDeoptimize(instr->environment()); 5363 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
5369 } else { 5364 // needed return address), even though the implementation of LAZY and EAGER is
5370 DeoptimizeIf(no_condition, instr->environment()); 5365 // now identical. When LAZY is eventually completely folded into EAGER, remove
5366 // the special case below.
5367 if (info()->IsStub() && type == Deoptimizer::EAGER) {
5368 type = Deoptimizer::LAZY;
5371 } 5369 }
5370 DeoptimizeIf(no_condition, instr->environment(), type);
5372 } 5371 }
5373 5372
5374 5373
5375 void LCodeGen::DoDummyUse(LDummyUse* instr) { 5374 void LCodeGen::DoDummyUse(LDummyUse* instr) {
5376 // Nothing to see here, move on! 5375 // Nothing to see here, move on!
5377 } 5376 }
5378 5377
5379 5378
5380 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 5379 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
5381 PushSafepointRegistersScope scope(this); 5380 PushSafepointRegistersScope scope(this);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
5538 FixedArray::kHeaderSize - kPointerSize)); 5537 FixedArray::kHeaderSize - kPointerSize));
5539 __ bind(&done); 5538 __ bind(&done);
5540 } 5539 }
5541 5540
5542 5541
5543 #undef __ 5542 #undef __
5544 5543
5545 } } // namespace v8::internal 5544 } } // namespace v8::internal
5546 5545
5547 #endif // V8_TARGET_ARCH_X64 5546 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698