| OLD | NEW |
| 1 // Copyright 2011 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 return result; | 1040 return result; |
| 1041 } | 1041 } |
| 1042 | 1042 |
| 1043 | 1043 |
| 1044 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { | 1044 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
| 1045 return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); | 1045 return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); |
| 1046 } | 1046 } |
| 1047 | 1047 |
| 1048 | 1048 |
| 1049 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { | 1049 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { |
| 1050 HValue* v = instr->value(); | 1050 HValue* value = instr->value(); |
| 1051 if (v->EmitAtUses()) { | 1051 if (value->EmitAtUses()) { |
| 1052 ASSERT(v->IsConstant()); | 1052 ASSERT(value->IsConstant()); |
| 1053 ASSERT(!v->representation().IsDouble()); | 1053 ASSERT(!value->representation().IsDouble()); |
| 1054 HBasicBlock* successor = HConstant::cast(v)->ToBoolean() | 1054 HBasicBlock* successor = HConstant::cast(value)->ToBoolean() |
| 1055 ? instr->FirstSuccessor() | 1055 ? instr->FirstSuccessor() |
| 1056 : instr->SecondSuccessor(); | 1056 : instr->SecondSuccessor(); |
| 1057 return new(zone()) LGoto(successor->block_id()); | 1057 return new(zone()) LGoto(successor->block_id()); |
| 1058 } | 1058 } |
| 1059 |
| 1060 // Untagged integers or doubles, smis and booleans don't require a |
| 1061 // deoptimization environment nor a temp register. |
| 1062 Representation rep = value->representation(); |
| 1063 HType type = value->type(); |
| 1064 if (!rep.IsTagged() || type.IsSmi() || type.IsBoolean()) { |
| 1065 return new(zone()) LBranch(UseRegister(value), NULL); |
| 1066 } |
| 1067 |
| 1059 ToBooleanStub::Types expected = instr->expected_input_types(); | 1068 ToBooleanStub::Types expected = instr->expected_input_types(); |
| 1060 // We need a temporary register when we have to access the map *or* we have | 1069 // We need a temporary register when we have to access the map *or* we have |
| 1061 // no type info yet, in which case we handle all cases (including the ones | 1070 // no type info yet, in which case we handle all cases (including the ones |
| 1062 // involving maps). | 1071 // involving maps). |
| 1063 bool needs_temp = expected.NeedsMap() || expected.IsEmpty(); | 1072 bool needs_temp = expected.NeedsMap() || expected.IsEmpty(); |
| 1064 LOperand* temp = needs_temp ? TempRegister() : NULL; | 1073 LOperand* temp = needs_temp ? TempRegister() : NULL; |
| 1065 return AssignEnvironment(new(zone()) LBranch(UseRegister(v), temp)); | 1074 return AssignEnvironment(new(zone()) LBranch(UseRegister(value), temp)); |
| 1066 } | 1075 } |
| 1067 | 1076 |
| 1068 | 1077 |
| 1069 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 1078 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 1070 ASSERT(instr->value()->representation().IsTagged()); | 1079 ASSERT(instr->value()->representation().IsTagged()); |
| 1071 LOperand* value = UseRegisterAtStart(instr->value()); | 1080 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1072 return new(zone()) LCmpMapAndBranch(value); | 1081 return new(zone()) LCmpMapAndBranch(value); |
| 1073 } | 1082 } |
| 1074 | 1083 |
| 1075 | 1084 |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 if (instr->representation().IsInteger32()) { | 1390 if (instr->representation().IsInteger32()) { |
| 1382 ASSERT(instr->left()->representation().IsInteger32()); | 1391 ASSERT(instr->left()->representation().IsInteger32()); |
| 1383 ASSERT(instr->right()->representation().IsInteger32()); | 1392 ASSERT(instr->right()->representation().IsInteger32()); |
| 1384 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); | 1393 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); |
| 1385 LOperand* right = UseOrConstant(instr->MostConstantOperand()); | 1394 LOperand* right = UseOrConstant(instr->MostConstantOperand()); |
| 1386 LOperand* temp = NULL; | 1395 LOperand* temp = NULL; |
| 1387 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1396 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1388 temp = TempRegister(); | 1397 temp = TempRegister(); |
| 1389 } | 1398 } |
| 1390 LMulI* mul = new(zone()) LMulI(left, right, temp); | 1399 LMulI* mul = new(zone()) LMulI(left, right, temp); |
| 1391 return AssignEnvironment(DefineSameAsFirst(mul)); | 1400 if (instr->CheckFlag(HValue::kCanOverflow) || |
| 1401 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1402 AssignEnvironment(mul); |
| 1403 } |
| 1404 return DefineSameAsFirst(mul); |
| 1392 } else if (instr->representation().IsDouble()) { | 1405 } else if (instr->representation().IsDouble()) { |
| 1393 return DoArithmeticD(Token::MUL, instr); | 1406 return DoArithmeticD(Token::MUL, instr); |
| 1394 } else { | 1407 } else { |
| 1395 ASSERT(instr->representation().IsTagged()); | 1408 ASSERT(instr->representation().IsTagged()); |
| 1396 return DoArithmeticT(Token::MUL, instr); | 1409 return DoArithmeticT(Token::MUL, instr); |
| 1397 } | 1410 } |
| 1398 } | 1411 } |
| 1399 | 1412 |
| 1400 | 1413 |
| 1401 LInstruction* LChunkBuilder::DoSub(HSub* instr) { | 1414 LInstruction* LChunkBuilder::DoSub(HSub* instr) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1449 LOperand* left = UseFixedDouble(instr->left(), xmm2); | 1462 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
| 1450 LOperand* right = exponent_type.IsDouble() ? | 1463 LOperand* right = exponent_type.IsDouble() ? |
| 1451 UseFixedDouble(instr->right(), xmm1) : | 1464 UseFixedDouble(instr->right(), xmm1) : |
| 1452 UseFixed(instr->right(), eax); | 1465 UseFixed(instr->right(), eax); |
| 1453 LPower* result = new(zone()) LPower(left, right); | 1466 LPower* result = new(zone()) LPower(left, right); |
| 1454 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, | 1467 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, |
| 1455 CAN_DEOPTIMIZE_EAGERLY); | 1468 CAN_DEOPTIMIZE_EAGERLY); |
| 1456 } | 1469 } |
| 1457 | 1470 |
| 1458 | 1471 |
| 1472 LInstruction* LChunkBuilder::DoRandom(HRandom* instr) { |
| 1473 ASSERT(instr->representation().IsDouble()); |
| 1474 ASSERT(instr->global_object()->representation().IsTagged()); |
| 1475 LOperand* global_object = UseFixed(instr->global_object(), eax); |
| 1476 LRandom* result = new(zone()) LRandom(global_object); |
| 1477 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1478 } |
| 1479 |
| 1480 |
| 1459 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { | 1481 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { |
| 1460 ASSERT(instr->left()->representation().IsTagged()); | 1482 ASSERT(instr->left()->representation().IsTagged()); |
| 1461 ASSERT(instr->right()->representation().IsTagged()); | 1483 ASSERT(instr->right()->representation().IsTagged()); |
| 1462 LOperand* context = UseFixed(instr->context(), esi); | 1484 LOperand* context = UseFixed(instr->context(), esi); |
| 1463 LOperand* left = UseFixed(instr->left(), edx); | 1485 LOperand* left = UseFixed(instr->left(), edx); |
| 1464 LOperand* right = UseFixed(instr->right(), eax); | 1486 LOperand* right = UseFixed(instr->right(), eax); |
| 1465 LCmpT* result = new(zone()) LCmpT(context, left, right); | 1487 LCmpT* result = new(zone()) LCmpT(context, left, right); |
| 1466 return MarkAsCall(DefineFixed(result, eax), instr); | 1488 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1467 } | 1489 } |
| 1468 | 1490 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1581 HHasCachedArrayIndexAndBranch* instr) { | 1603 HHasCachedArrayIndexAndBranch* instr) { |
| 1582 ASSERT(instr->value()->representation().IsTagged()); | 1604 ASSERT(instr->value()->representation().IsTagged()); |
| 1583 return new(zone()) LHasCachedArrayIndexAndBranch( | 1605 return new(zone()) LHasCachedArrayIndexAndBranch( |
| 1584 UseRegisterAtStart(instr->value())); | 1606 UseRegisterAtStart(instr->value())); |
| 1585 } | 1607 } |
| 1586 | 1608 |
| 1587 | 1609 |
| 1588 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( | 1610 LInstruction* LChunkBuilder::DoClassOfTestAndBranch( |
| 1589 HClassOfTestAndBranch* instr) { | 1611 HClassOfTestAndBranch* instr) { |
| 1590 ASSERT(instr->value()->representation().IsTagged()); | 1612 ASSERT(instr->value()->representation().IsTagged()); |
| 1591 return new(zone()) LClassOfTestAndBranch(UseTempRegister(instr->value()), | 1613 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()), |
| 1592 TempRegister(), | 1614 TempRegister(), |
| 1593 TempRegister()); | 1615 TempRegister()); |
| 1594 } | 1616 } |
| 1595 | 1617 |
| 1596 | 1618 |
| 1597 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { | 1619 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { |
| 1598 LOperand* array = UseRegisterAtStart(instr->value()); | 1620 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1599 return DefineAsRegister(new(zone()) LJSArrayLength(array)); | 1621 return DefineAsRegister(new(zone()) LJSArrayLength(array)); |
| 1600 } | 1622 } |
| 1601 | 1623 |
| 1602 | 1624 |
| 1603 LInstruction* LChunkBuilder::DoFixedArrayBaseLength( | 1625 LInstruction* LChunkBuilder::DoFixedArrayBaseLength( |
| 1604 HFixedArrayBaseLength* instr) { | 1626 HFixedArrayBaseLength* instr) { |
| 1605 LOperand* array = UseRegisterAtStart(instr->value()); | 1627 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1606 return DefineAsRegister(new(zone()) LFixedArrayBaseLength(array)); | 1628 return DefineAsRegister(new(zone()) LFixedArrayBaseLength(array)); |
| 1607 } | 1629 } |
| 1608 | 1630 |
| 1609 | 1631 |
| 1610 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) { | 1632 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) { |
| 1611 LOperand* object = UseRegisterAtStart(instr->value()); | 1633 LOperand* object = UseRegisterAtStart(instr->value()); |
| 1612 return DefineAsRegister(new(zone()) LElementsKind(object)); | 1634 return DefineAsRegister(new(zone()) LElementsKind(object)); |
| 1613 } | 1635 } |
| 1614 | 1636 |
| 1615 | 1637 |
| 1616 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1638 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1617 LOperand* object = UseRegister(instr->value()); | 1639 LOperand* object = UseRegister(instr->value()); |
| 1618 LValueOf* result = new(zone()) LValueOf(object, TempRegister()); | 1640 LValueOf* result = new(zone()) LValueOf(object, TempRegister()); |
| 1619 return AssignEnvironment(DefineSameAsFirst(result)); | 1641 return DefineSameAsFirst(result); |
| 1620 } | 1642 } |
| 1621 | 1643 |
| 1622 | 1644 |
| 1623 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1645 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1624 return AssignEnvironment(new(zone()) LBoundsCheck( | 1646 return AssignEnvironment(new(zone()) LBoundsCheck( |
| 1625 UseRegisterOrConstantAtStart(instr->index()), | 1647 UseRegisterOrConstantAtStart(instr->index()), |
| 1626 UseAtStart(instr->length()))); | 1648 UseAtStart(instr->length()))); |
| 1627 } | 1649 } |
| 1628 | 1650 |
| 1629 | 1651 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1653 return NULL; | 1675 return NULL; |
| 1654 } | 1676 } |
| 1655 | 1677 |
| 1656 | 1678 |
| 1657 LInstruction* LChunkBuilder::DoChange(HChange* instr) { | 1679 LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
| 1658 Representation from = instr->from(); | 1680 Representation from = instr->from(); |
| 1659 Representation to = instr->to(); | 1681 Representation to = instr->to(); |
| 1660 if (from.IsTagged()) { | 1682 if (from.IsTagged()) { |
| 1661 if (to.IsDouble()) { | 1683 if (to.IsDouble()) { |
| 1662 LOperand* value = UseRegister(instr->value()); | 1684 LOperand* value = UseRegister(instr->value()); |
| 1663 LNumberUntagD* res = new(zone()) LNumberUntagD(value); | 1685 // Temp register only necessary for minus zero check. |
| 1686 LOperand* temp = instr->deoptimize_on_minus_zero() |
| 1687 ? TempRegister() |
| 1688 : NULL; |
| 1689 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); |
| 1664 return AssignEnvironment(DefineAsRegister(res)); | 1690 return AssignEnvironment(DefineAsRegister(res)); |
| 1665 } else { | 1691 } else { |
| 1666 ASSERT(to.IsInteger32()); | 1692 ASSERT(to.IsInteger32()); |
| 1667 LOperand* value = UseRegister(instr->value()); | 1693 LOperand* value = UseRegister(instr->value()); |
| 1668 bool needs_check = !instr->value()->type().IsSmi(); | 1694 bool needs_check = !instr->value()->type().IsSmi(); |
| 1669 if (needs_check) { | 1695 if (needs_check) { |
| 1670 bool truncating = instr->CanTruncateToInt32(); | 1696 bool truncating = instr->CanTruncateToInt32(); |
| 1671 LOperand* xmm_temp = | 1697 LOperand* xmm_temp = |
| 1672 (truncating && CpuFeatures::IsSupported(SSE3)) | 1698 (truncating && CpuFeatures::IsSupported(SSE3)) |
| 1673 ? NULL | 1699 ? NULL |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1949 } | 1975 } |
| 1950 | 1976 |
| 1951 | 1977 |
| 1952 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1978 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
| 1953 HLoadKeyedFastElement* instr) { | 1979 HLoadKeyedFastElement* instr) { |
| 1954 ASSERT(instr->representation().IsTagged()); | 1980 ASSERT(instr->representation().IsTagged()); |
| 1955 ASSERT(instr->key()->representation().IsInteger32()); | 1981 ASSERT(instr->key()->representation().IsInteger32()); |
| 1956 LOperand* obj = UseRegisterAtStart(instr->object()); | 1982 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1957 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 1983 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 1958 LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key); | 1984 LLoadKeyedFastElement* result = new(zone()) LLoadKeyedFastElement(obj, key); |
| 1959 return AssignEnvironment(DefineAsRegister(result)); | 1985 if (instr->RequiresHoleCheck()) AssignEnvironment(result); |
| 1986 return DefineAsRegister(result); |
| 1960 } | 1987 } |
| 1961 | 1988 |
| 1962 | 1989 |
| 1963 LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( | 1990 LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement( |
| 1964 HLoadKeyedFastDoubleElement* instr) { | 1991 HLoadKeyedFastDoubleElement* instr) { |
| 1965 ASSERT(instr->representation().IsDouble()); | 1992 ASSERT(instr->representation().IsDouble()); |
| 1966 ASSERT(instr->key()->representation().IsInteger32()); | 1993 ASSERT(instr->key()->representation().IsInteger32()); |
| 1967 LOperand* elements = UseRegisterAtStart(instr->elements()); | 1994 LOperand* elements = UseRegisterAtStart(instr->elements()); |
| 1968 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 1995 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 1969 LLoadKeyedFastDoubleElement* result = | 1996 LLoadKeyedFastDoubleElement* result = |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2374 LOperand* key = UseOrConstantAtStart(instr->key()); | 2401 LOperand* key = UseOrConstantAtStart(instr->key()); |
| 2375 LOperand* object = UseOrConstantAtStart(instr->object()); | 2402 LOperand* object = UseOrConstantAtStart(instr->object()); |
| 2376 LIn* result = new(zone()) LIn(context, key, object); | 2403 LIn* result = new(zone()) LIn(context, key, object); |
| 2377 return MarkAsCall(DefineFixed(result, eax), instr); | 2404 return MarkAsCall(DefineFixed(result, eax), instr); |
| 2378 } | 2405 } |
| 2379 | 2406 |
| 2380 | 2407 |
| 2381 } } // namespace v8::internal | 2408 } } // namespace v8::internal |
| 2382 | 2409 |
| 2383 #endif // V8_TARGET_ARCH_IA32 | 2410 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |