| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 // Don't base result on EFLAGS when a NaN is involved. Instead | 1278 // Don't base result on EFLAGS when a NaN is involved. Instead |
| 1279 // jump to the unordered case, which produces a false value. | 1279 // jump to the unordered case, which produces a false value. |
| 1280 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); | 1280 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); |
| 1281 __ j(parity_even, &unordered, not_taken); | 1281 __ j(parity_even, &unordered, not_taken); |
| 1282 } else { | 1282 } else { |
| 1283 EmitCmpI(left, right); | 1283 EmitCmpI(left, right); |
| 1284 } | 1284 } |
| 1285 | 1285 |
| 1286 NearLabel done; | 1286 NearLabel done; |
| 1287 Condition cc = TokenToCondition(instr->op(), instr->is_double()); | 1287 Condition cc = TokenToCondition(instr->op(), instr->is_double()); |
| 1288 __ mov(ToRegister(result), Handle<Object>(Heap::true_value())); | 1288 __ mov(ToRegister(result), Factory::true_value()); |
| 1289 __ j(cc, &done); | 1289 __ j(cc, &done); |
| 1290 | 1290 |
| 1291 __ bind(&unordered); | 1291 __ bind(&unordered); |
| 1292 __ mov(ToRegister(result), Handle<Object>(Heap::false_value())); | 1292 __ mov(ToRegister(result), Factory::false_value()); |
| 1293 __ bind(&done); | 1293 __ bind(&done); |
| 1294 } | 1294 } |
| 1295 | 1295 |
| 1296 | 1296 |
| 1297 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 1297 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { |
| 1298 LOperand* left = instr->InputAt(0); | 1298 LOperand* left = instr->InputAt(0); |
| 1299 LOperand* right = instr->InputAt(1); | 1299 LOperand* right = instr->InputAt(1); |
| 1300 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1300 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1301 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1301 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1302 | 1302 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1313 EmitBranch(true_block, false_block, cc); | 1313 EmitBranch(true_block, false_block, cc); |
| 1314 } | 1314 } |
| 1315 | 1315 |
| 1316 | 1316 |
| 1317 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { | 1317 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { |
| 1318 Register left = ToRegister(instr->InputAt(0)); | 1318 Register left = ToRegister(instr->InputAt(0)); |
| 1319 Register right = ToRegister(instr->InputAt(1)); | 1319 Register right = ToRegister(instr->InputAt(1)); |
| 1320 Register result = ToRegister(instr->result()); | 1320 Register result = ToRegister(instr->result()); |
| 1321 | 1321 |
| 1322 __ cmp(left, Operand(right)); | 1322 __ cmp(left, Operand(right)); |
| 1323 __ mov(result, Handle<Object>(Heap::true_value())); | 1323 __ mov(result, Factory::true_value()); |
| 1324 NearLabel done; | 1324 NearLabel done; |
| 1325 __ j(equal, &done); | 1325 __ j(equal, &done); |
| 1326 __ mov(result, Handle<Object>(Heap::false_value())); | 1326 __ mov(result, Factory::false_value()); |
| 1327 __ bind(&done); | 1327 __ bind(&done); |
| 1328 } | 1328 } |
| 1329 | 1329 |
| 1330 | 1330 |
| 1331 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { | 1331 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { |
| 1332 Register left = ToRegister(instr->InputAt(0)); | 1332 Register left = ToRegister(instr->InputAt(0)); |
| 1333 Register right = ToRegister(instr->InputAt(1)); | 1333 Register right = ToRegister(instr->InputAt(1)); |
| 1334 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1334 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1335 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1335 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1336 | 1336 |
| 1337 __ cmp(left, Operand(right)); | 1337 __ cmp(left, Operand(right)); |
| 1338 EmitBranch(true_block, false_block, equal); | 1338 EmitBranch(true_block, false_block, equal); |
| 1339 } | 1339 } |
| 1340 | 1340 |
| 1341 | 1341 |
| 1342 void LCodeGen::DoIsNull(LIsNull* instr) { | 1342 void LCodeGen::DoIsNull(LIsNull* instr) { |
| 1343 Register reg = ToRegister(instr->InputAt(0)); | 1343 Register reg = ToRegister(instr->InputAt(0)); |
| 1344 Register result = ToRegister(instr->result()); | 1344 Register result = ToRegister(instr->result()); |
| 1345 | 1345 |
| 1346 // TODO(fsc): If the expression is known to be a smi, then it's | 1346 // TODO(fsc): If the expression is known to be a smi, then it's |
| 1347 // definitely not null. Materialize false. | 1347 // definitely not null. Materialize false. |
| 1348 | 1348 |
| 1349 __ cmp(reg, Factory::null_value()); | 1349 __ cmp(reg, Factory::null_value()); |
| 1350 if (instr->is_strict()) { | 1350 if (instr->is_strict()) { |
| 1351 __ mov(result, Handle<Object>(Heap::true_value())); | 1351 __ mov(result, Factory::true_value()); |
| 1352 NearLabel done; | 1352 NearLabel done; |
| 1353 __ j(equal, &done); | 1353 __ j(equal, &done); |
| 1354 __ mov(result, Handle<Object>(Heap::false_value())); | 1354 __ mov(result, Factory::false_value()); |
| 1355 __ bind(&done); | 1355 __ bind(&done); |
| 1356 } else { | 1356 } else { |
| 1357 NearLabel true_value, false_value, done; | 1357 NearLabel true_value, false_value, done; |
| 1358 __ j(equal, &true_value); | 1358 __ j(equal, &true_value); |
| 1359 __ cmp(reg, Factory::undefined_value()); | 1359 __ cmp(reg, Factory::undefined_value()); |
| 1360 __ j(equal, &true_value); | 1360 __ j(equal, &true_value); |
| 1361 __ test(reg, Immediate(kSmiTagMask)); | 1361 __ test(reg, Immediate(kSmiTagMask)); |
| 1362 __ j(zero, &false_value); | 1362 __ j(zero, &false_value); |
| 1363 // Check for undetectable objects by looking in the bit field in | 1363 // Check for undetectable objects by looking in the bit field in |
| 1364 // the map. The object has already been smi checked. | 1364 // the map. The object has already been smi checked. |
| 1365 Register scratch = result; | 1365 Register scratch = result; |
| 1366 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 1366 __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); |
| 1367 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); | 1367 __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); |
| 1368 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); | 1368 __ test(scratch, Immediate(1 << Map::kIsUndetectable)); |
| 1369 __ j(not_zero, &true_value); | 1369 __ j(not_zero, &true_value); |
| 1370 __ bind(&false_value); | 1370 __ bind(&false_value); |
| 1371 __ mov(result, Handle<Object>(Heap::false_value())); | 1371 __ mov(result, Factory::false_value()); |
| 1372 __ jmp(&done); | 1372 __ jmp(&done); |
| 1373 __ bind(&true_value); | 1373 __ bind(&true_value); |
| 1374 __ mov(result, Handle<Object>(Heap::true_value())); | 1374 __ mov(result, Factory::true_value()); |
| 1375 __ bind(&done); | 1375 __ bind(&done); |
| 1376 } | 1376 } |
| 1377 } | 1377 } |
| 1378 | 1378 |
| 1379 | 1379 |
| 1380 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { | 1380 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { |
| 1381 Register reg = ToRegister(instr->InputAt(0)); | 1381 Register reg = ToRegister(instr->InputAt(0)); |
| 1382 | 1382 |
| 1383 // TODO(fsc): If the expression is known to be a smi, then it's | 1383 // TODO(fsc): If the expression is known to be a smi, then it's |
| 1384 // definitely not null. Jump to the false block. | 1384 // definitely not null. Jump to the false block. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1440 void LCodeGen::DoIsObject(LIsObject* instr) { | 1440 void LCodeGen::DoIsObject(LIsObject* instr) { |
| 1441 Register reg = ToRegister(instr->InputAt(0)); | 1441 Register reg = ToRegister(instr->InputAt(0)); |
| 1442 Register result = ToRegister(instr->result()); | 1442 Register result = ToRegister(instr->result()); |
| 1443 Register temp = ToRegister(instr->TempAt(0)); | 1443 Register temp = ToRegister(instr->TempAt(0)); |
| 1444 Label is_false, is_true, done; | 1444 Label is_false, is_true, done; |
| 1445 | 1445 |
| 1446 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); | 1446 Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); |
| 1447 __ j(true_cond, &is_true); | 1447 __ j(true_cond, &is_true); |
| 1448 | 1448 |
| 1449 __ bind(&is_false); | 1449 __ bind(&is_false); |
| 1450 __ mov(result, Handle<Object>(Heap::false_value())); | 1450 __ mov(result, Factory::false_value()); |
| 1451 __ jmp(&done); | 1451 __ jmp(&done); |
| 1452 | 1452 |
| 1453 __ bind(&is_true); | 1453 __ bind(&is_true); |
| 1454 __ mov(result, Handle<Object>(Heap::true_value())); | 1454 __ mov(result, Factory::true_value()); |
| 1455 | 1455 |
| 1456 __ bind(&done); | 1456 __ bind(&done); |
| 1457 } | 1457 } |
| 1458 | 1458 |
| 1459 | 1459 |
| 1460 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { | 1460 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { |
| 1461 Register reg = ToRegister(instr->InputAt(0)); | 1461 Register reg = ToRegister(instr->InputAt(0)); |
| 1462 Register temp = ToRegister(instr->TempAt(0)); | 1462 Register temp = ToRegister(instr->TempAt(0)); |
| 1463 Register temp2 = ToRegister(instr->TempAt(1)); | 1463 Register temp2 = ToRegister(instr->TempAt(1)); |
| 1464 | 1464 |
| 1465 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1465 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1466 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1466 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1467 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1467 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1468 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1468 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1469 | 1469 |
| 1470 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); | 1470 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); |
| 1471 | 1471 |
| 1472 EmitBranch(true_block, false_block, true_cond); | 1472 EmitBranch(true_block, false_block, true_cond); |
| 1473 } | 1473 } |
| 1474 | 1474 |
| 1475 | 1475 |
| 1476 void LCodeGen::DoIsSmi(LIsSmi* instr) { | 1476 void LCodeGen::DoIsSmi(LIsSmi* instr) { |
| 1477 Operand input = ToOperand(instr->InputAt(0)); | 1477 Operand input = ToOperand(instr->InputAt(0)); |
| 1478 Register result = ToRegister(instr->result()); | 1478 Register result = ToRegister(instr->result()); |
| 1479 | 1479 |
| 1480 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1480 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1481 __ test(input, Immediate(kSmiTagMask)); | 1481 __ test(input, Immediate(kSmiTagMask)); |
| 1482 __ mov(result, Handle<Object>(Heap::true_value())); | 1482 __ mov(result, Factory::true_value()); |
| 1483 NearLabel done; | 1483 NearLabel done; |
| 1484 __ j(zero, &done); | 1484 __ j(zero, &done); |
| 1485 __ mov(result, Handle<Object>(Heap::false_value())); | 1485 __ mov(result, Factory::false_value()); |
| 1486 __ bind(&done); | 1486 __ bind(&done); |
| 1487 } | 1487 } |
| 1488 | 1488 |
| 1489 | 1489 |
| 1490 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 1490 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
| 1491 Operand input = ToOperand(instr->InputAt(0)); | 1491 Operand input = ToOperand(instr->InputAt(0)); |
| 1492 | 1492 |
| 1493 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1493 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1494 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1494 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1495 | 1495 |
| 1496 __ test(input, Immediate(kSmiTagMask)); | 1496 __ test(input, Immediate(kSmiTagMask)); |
| 1497 EmitBranch(true_block, false_block, zero); | 1497 EmitBranch(true_block, false_block, zero); |
| 1498 } | 1498 } |
| 1499 | 1499 |
| 1500 | 1500 |
| 1501 static InstanceType TestType(HHasInstanceType* instr) { | 1501 static InstanceType TestType(HHasInstanceType* instr) { |
| 1502 InstanceType from = instr->from(); | 1502 InstanceType from = instr->from(); |
| 1503 InstanceType to = instr->to(); | 1503 InstanceType to = instr->to(); |
| 1504 if (from == FIRST_TYPE) return to; | 1504 if (from == FIRST_TYPE) return to; |
| 1505 ASSERT(from == to || to == LAST_TYPE); | 1505 ASSERT(from == to || to == LAST_TYPE); |
| 1506 return from; | 1506 return from; |
| 1507 } | 1507 } |
| 1508 | 1508 |
| 1509 | 1509 |
| 1510 | |
| 1511 static Condition BranchCondition(HHasInstanceType* instr) { | 1510 static Condition BranchCondition(HHasInstanceType* instr) { |
| 1512 InstanceType from = instr->from(); | 1511 InstanceType from = instr->from(); |
| 1513 InstanceType to = instr->to(); | 1512 InstanceType to = instr->to(); |
| 1514 if (from == to) return equal; | 1513 if (from == to) return equal; |
| 1515 if (to == LAST_TYPE) return above_equal; | 1514 if (to == LAST_TYPE) return above_equal; |
| 1516 if (from == FIRST_TYPE) return below_equal; | 1515 if (from == FIRST_TYPE) return below_equal; |
| 1517 UNREACHABLE(); | 1516 UNREACHABLE(); |
| 1518 return equal; | 1517 return equal; |
| 1519 } | 1518 } |
| 1520 | 1519 |
| 1521 | 1520 |
| 1522 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { | 1521 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { |
| 1523 Register input = ToRegister(instr->InputAt(0)); | 1522 Register input = ToRegister(instr->InputAt(0)); |
| 1524 Register result = ToRegister(instr->result()); | 1523 Register result = ToRegister(instr->result()); |
| 1525 | 1524 |
| 1526 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1525 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1527 __ test(input, Immediate(kSmiTagMask)); | 1526 __ test(input, Immediate(kSmiTagMask)); |
| 1528 NearLabel done, is_false; | 1527 NearLabel done, is_false; |
| 1529 __ j(zero, &is_false); | 1528 __ j(zero, &is_false); |
| 1530 __ CmpObjectType(input, TestType(instr->hydrogen()), result); | 1529 __ CmpObjectType(input, TestType(instr->hydrogen()), result); |
| 1531 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); | 1530 __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); |
| 1532 __ mov(result, Handle<Object>(Heap::true_value())); | 1531 __ mov(result, Factory::true_value()); |
| 1533 __ jmp(&done); | 1532 __ jmp(&done); |
| 1534 __ bind(&is_false); | 1533 __ bind(&is_false); |
| 1535 __ mov(result, Handle<Object>(Heap::false_value())); | 1534 __ mov(result, Factory::false_value()); |
| 1536 __ bind(&done); | 1535 __ bind(&done); |
| 1537 } | 1536 } |
| 1538 | 1537 |
| 1539 | 1538 |
| 1540 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 1539 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
| 1541 Register input = ToRegister(instr->InputAt(0)); | 1540 Register input = ToRegister(instr->InputAt(0)); |
| 1542 Register temp = ToRegister(instr->TempAt(0)); | 1541 Register temp = ToRegister(instr->TempAt(0)); |
| 1543 | 1542 |
| 1544 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1543 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1545 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1544 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1546 | 1545 |
| 1547 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1546 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1548 | 1547 |
| 1549 __ test(input, Immediate(kSmiTagMask)); | 1548 __ test(input, Immediate(kSmiTagMask)); |
| 1550 __ j(zero, false_label); | 1549 __ j(zero, false_label); |
| 1551 | 1550 |
| 1552 __ CmpObjectType(input, TestType(instr->hydrogen()), temp); | 1551 __ CmpObjectType(input, TestType(instr->hydrogen()), temp); |
| 1553 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); | 1552 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); |
| 1554 } | 1553 } |
| 1555 | 1554 |
| 1556 | 1555 |
| 1557 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { | 1556 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { |
| 1558 Register input = ToRegister(instr->InputAt(0)); | 1557 Register input = ToRegister(instr->InputAt(0)); |
| 1559 Register result = ToRegister(instr->result()); | 1558 Register result = ToRegister(instr->result()); |
| 1560 | 1559 |
| 1561 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1560 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
| 1562 __ mov(result, Handle<Object>(Heap::true_value())); | 1561 __ mov(result, Factory::true_value()); |
| 1563 __ test(FieldOperand(input, String::kHashFieldOffset), | 1562 __ test(FieldOperand(input, String::kHashFieldOffset), |
| 1564 Immediate(String::kContainsCachedArrayIndexMask)); | 1563 Immediate(String::kContainsCachedArrayIndexMask)); |
| 1565 NearLabel done; | 1564 NearLabel done; |
| 1566 __ j(not_zero, &done); | 1565 __ j(not_zero, &done); |
| 1567 __ mov(result, Handle<Object>(Heap::false_value())); | 1566 __ mov(result, Factory::false_value()); |
| 1568 __ bind(&done); | 1567 __ bind(&done); |
| 1569 } | 1568 } |
| 1570 | 1569 |
| 1571 | 1570 |
| 1572 void LCodeGen::DoHasCachedArrayIndexAndBranch( | 1571 void LCodeGen::DoHasCachedArrayIndexAndBranch( |
| 1573 LHasCachedArrayIndexAndBranch* instr) { | 1572 LHasCachedArrayIndexAndBranch* instr) { |
| 1574 Register input = ToRegister(instr->InputAt(0)); | 1573 Register input = ToRegister(instr->InputAt(0)); |
| 1575 | 1574 |
| 1576 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1575 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1577 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1576 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1646 Register temp = ToRegister(instr->TempAt(0)); | 1645 Register temp = ToRegister(instr->TempAt(0)); |
| 1647 Handle<String> class_name = instr->hydrogen()->class_name(); | 1646 Handle<String> class_name = instr->hydrogen()->class_name(); |
| 1648 NearLabel done; | 1647 NearLabel done; |
| 1649 Label is_true, is_false; | 1648 Label is_true, is_false; |
| 1650 | 1649 |
| 1651 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); | 1650 EmitClassOfTest(&is_true, &is_false, class_name, input, temp, input); |
| 1652 | 1651 |
| 1653 __ j(not_equal, &is_false); | 1652 __ j(not_equal, &is_false); |
| 1654 | 1653 |
| 1655 __ bind(&is_true); | 1654 __ bind(&is_true); |
| 1656 __ mov(result, Handle<Object>(Heap::true_value())); | 1655 __ mov(result, Factory::true_value()); |
| 1657 __ jmp(&done); | 1656 __ jmp(&done); |
| 1658 | 1657 |
| 1659 __ bind(&is_false); | 1658 __ bind(&is_false); |
| 1660 __ mov(result, Handle<Object>(Heap::false_value())); | 1659 __ mov(result, Factory::false_value()); |
| 1661 __ bind(&done); | 1660 __ bind(&done); |
| 1662 } | 1661 } |
| 1663 | 1662 |
| 1664 | 1663 |
| 1665 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { | 1664 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { |
| 1666 Register input = ToRegister(instr->InputAt(0)); | 1665 Register input = ToRegister(instr->InputAt(0)); |
| 1667 Register temp = ToRegister(instr->TempAt(0)); | 1666 Register temp = ToRegister(instr->TempAt(0)); |
| 1668 Register temp2 = ToRegister(instr->TempAt(1)); | 1667 Register temp2 = ToRegister(instr->TempAt(1)); |
| 1669 if (input.is(temp)) { | 1668 if (input.is(temp)) { |
| 1670 // Swap. | 1669 // Swap. |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2214 | 2213 |
| 2215 Label done; | 2214 Label done; |
| 2216 Register tmp = input_reg.is(eax) ? ecx : eax; | 2215 Register tmp = input_reg.is(eax) ? ecx : eax; |
| 2217 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; | 2216 Register tmp2 = tmp.is(ecx) ? edx : input_reg.is(ecx) ? edx : ecx; |
| 2218 | 2217 |
| 2219 // Preserve the value of all registers. | 2218 // Preserve the value of all registers. |
| 2220 __ PushSafepointRegisters(); | 2219 __ PushSafepointRegisters(); |
| 2221 | 2220 |
| 2222 Label negative; | 2221 Label negative; |
| 2223 __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 2222 __ mov(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
| 2224 // Check the sign of the argument. If the argument is positive, | 2223 // Check the sign of the argument. If the argument is positive, just |
| 2225 // just return it. | 2224 // return it. We do not need to patch the stack since |input| and |
| 2225 // |result| are the same register and |input| will be restored |
| 2226 // unchanged by popping safepoint registers. |
| 2226 __ test(tmp, Immediate(HeapNumber::kSignMask)); | 2227 __ test(tmp, Immediate(HeapNumber::kSignMask)); |
| 2227 __ j(not_zero, &negative); | 2228 __ j(not_zero, &negative); |
| 2228 __ mov(tmp, input_reg); | |
| 2229 __ jmp(&done); | 2229 __ jmp(&done); |
| 2230 | 2230 |
| 2231 __ bind(&negative); | 2231 __ bind(&negative); |
| 2232 | 2232 |
| 2233 Label allocated, slow; | 2233 Label allocated, slow; |
| 2234 __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow); | 2234 __ AllocateHeapNumber(tmp, tmp2, no_reg, &slow); |
| 2235 __ jmp(&allocated); | 2235 __ jmp(&allocated); |
| 2236 | 2236 |
| 2237 // Slow case: Call the runtime system to do the number allocation. | 2237 // Slow case: Call the runtime system to do the number allocation. |
| 2238 __ bind(&slow); | 2238 __ bind(&slow); |
| 2239 | 2239 |
| 2240 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 2240 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 2241 RecordSafepointWithRegisters( | 2241 RecordSafepointWithRegisters( |
| 2242 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | 2242 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); |
| 2243 // Set the pointer to the new heap number in tmp. | 2243 // Set the pointer to the new heap number in tmp. |
| 2244 if (!tmp.is(eax)) __ mov(tmp, eax); | 2244 if (!tmp.is(eax)) __ mov(tmp, eax); |
| 2245 | 2245 |
| 2246 // Restore input_reg after call to runtime. | 2246 // Restore input_reg after call to runtime. |
| 2247 __ mov(input_reg, Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize)); | 2247 __ mov(input_reg, Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize)); |
| 2248 | 2248 |
| 2249 __ bind(&allocated); | 2249 __ bind(&allocated); |
| 2250 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 2250 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
| 2251 __ and_(tmp2, ~HeapNumber::kSignMask); | 2251 __ and_(tmp2, ~HeapNumber::kSignMask); |
| 2252 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); | 2252 __ mov(FieldOperand(tmp, HeapNumber::kExponentOffset), tmp2); |
| 2253 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); | 2253 __ mov(tmp2, FieldOperand(input_reg, HeapNumber::kMantissaOffset)); |
| 2254 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); | 2254 __ mov(FieldOperand(tmp, HeapNumber::kMantissaOffset), tmp2); |
| 2255 __ mov(Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize), tmp); |
| 2255 | 2256 |
| 2256 __ bind(&done); | 2257 __ bind(&done); |
| 2257 __ mov(Operand(esp, EspIndexForPushAll(input_reg) * kPointerSize), tmp); | 2258 __ PopSafepointRegisters(); |
| 2259 } |
| 2258 | 2260 |
| 2259 __ PopSafepointRegisters(); | 2261 |
| 2262 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { |
| 2263 Register input_reg = ToRegister(instr->InputAt(0)); |
| 2264 __ test(input_reg, Operand(input_reg)); |
| 2265 Label is_positive; |
| 2266 __ j(not_sign, &is_positive); |
| 2267 __ neg(input_reg); |
| 2268 __ test(input_reg, Operand(input_reg)); |
| 2269 DeoptimizeIf(negative, instr->environment()); |
| 2270 __ bind(&is_positive); |
| 2260 } | 2271 } |
| 2261 | 2272 |
| 2262 | 2273 |
| 2263 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 2274 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
| 2264 // Class for deferred case. | 2275 // Class for deferred case. |
| 2265 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 2276 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 2266 public: | 2277 public: |
| 2267 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 2278 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
| 2268 LUnaryMathOperation* instr) | 2279 LUnaryMathOperation* instr) |
| 2269 : LDeferredCode(codegen), instr_(instr) { } | 2280 : LDeferredCode(codegen), instr_(instr) { } |
| 2270 virtual void Generate() { | 2281 virtual void Generate() { |
| 2271 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 2282 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
| 2272 } | 2283 } |
| 2273 private: | 2284 private: |
| 2274 LUnaryMathOperation* instr_; | 2285 LUnaryMathOperation* instr_; |
| 2275 }; | 2286 }; |
| 2276 | 2287 |
| 2277 ASSERT(instr->InputAt(0)->Equals(instr->result())); | 2288 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
| 2278 Representation r = instr->hydrogen()->value()->representation(); | 2289 Representation r = instr->hydrogen()->value()->representation(); |
| 2279 | 2290 |
| 2280 if (r.IsDouble()) { | 2291 if (r.IsDouble()) { |
| 2281 XMMRegister scratch = xmm0; | 2292 XMMRegister scratch = xmm0; |
| 2282 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 2293 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| 2283 __ pxor(scratch, scratch); | 2294 __ pxor(scratch, scratch); |
| 2284 __ subsd(scratch, input_reg); | 2295 __ subsd(scratch, input_reg); |
| 2285 __ pand(input_reg, scratch); | 2296 __ pand(input_reg, scratch); |
| 2286 } else if (r.IsInteger32()) { | 2297 } else if (r.IsInteger32()) { |
| 2287 Register input_reg = ToRegister(instr->InputAt(0)); | 2298 EmitIntegerMathAbs(instr); |
| 2288 __ test(input_reg, Operand(input_reg)); | |
| 2289 Label is_positive; | |
| 2290 __ j(not_sign, &is_positive); | |
| 2291 __ neg(input_reg); | |
| 2292 __ test(input_reg, Operand(input_reg)); | |
| 2293 DeoptimizeIf(negative, instr->environment()); | |
| 2294 __ bind(&is_positive); | |
| 2295 } else { // Tagged case. | 2299 } else { // Tagged case. |
| 2296 DeferredMathAbsTaggedHeapNumber* deferred = | 2300 DeferredMathAbsTaggedHeapNumber* deferred = |
| 2297 new DeferredMathAbsTaggedHeapNumber(this, instr); | 2301 new DeferredMathAbsTaggedHeapNumber(this, instr); |
| 2298 Label not_smi; | |
| 2299 Register input_reg = ToRegister(instr->InputAt(0)); | 2302 Register input_reg = ToRegister(instr->InputAt(0)); |
| 2300 // Smi check. | 2303 // Smi check. |
| 2301 __ test(input_reg, Immediate(kSmiTagMask)); | 2304 __ test(input_reg, Immediate(kSmiTagMask)); |
| 2302 __ j(not_zero, deferred->entry()); | 2305 __ j(not_zero, deferred->entry()); |
| 2303 __ test(input_reg, Operand(input_reg)); | 2306 EmitIntegerMathAbs(instr); |
| 2304 Label is_positive; | |
| 2305 __ j(not_sign, &is_positive); | |
| 2306 __ neg(input_reg); | |
| 2307 | |
| 2308 __ test(input_reg, Operand(input_reg)); | |
| 2309 DeoptimizeIf(negative, instr->environment()); | |
| 2310 | |
| 2311 __ bind(&is_positive); | |
| 2312 __ bind(deferred->exit()); | 2307 __ bind(deferred->exit()); |
| 2313 } | 2308 } |
| 2314 } | 2309 } |
| 2315 | 2310 |
| 2316 | 2311 |
| 2317 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 2312 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| 2318 XMMRegister xmm_scratch = xmm0; | 2313 XMMRegister xmm_scratch = xmm0; |
| 2319 Register output_reg = ToRegister(instr->result()); | 2314 Register output_reg = ToRegister(instr->result()); |
| 2320 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 2315 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
| 2321 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. | 2316 __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2644 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { | 2639 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
| 2645 ASSERT(ToRegister(instr->object()).is(edx)); | 2640 ASSERT(ToRegister(instr->object()).is(edx)); |
| 2646 ASSERT(ToRegister(instr->key()).is(ecx)); | 2641 ASSERT(ToRegister(instr->key()).is(ecx)); |
| 2647 ASSERT(ToRegister(instr->value()).is(eax)); | 2642 ASSERT(ToRegister(instr->value()).is(eax)); |
| 2648 | 2643 |
| 2649 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 2644 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 2650 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2645 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2651 } | 2646 } |
| 2652 | 2647 |
| 2653 | 2648 |
| 2649 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 2650 class DeferredStringCharCodeAt: public LDeferredCode { |
| 2651 public: |
| 2652 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| 2653 : LDeferredCode(codegen), instr_(instr) { } |
| 2654 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } |
| 2655 private: |
| 2656 LStringCharCodeAt* instr_; |
| 2657 }; |
| 2658 |
| 2659 Register string = ToRegister(instr->string()); |
| 2660 Register index = no_reg; |
| 2661 int const_index = -1; |
| 2662 if (instr->index()->IsConstantOperand()) { |
| 2663 const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
| 2664 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); |
| 2665 if (!Smi::IsValid(const_index)) { |
| 2666 // Guaranteed to be out of bounds because of the assert above. |
| 2667 // So the bounds check that must dominate this instruction must |
| 2668 // have deoptimized already. |
| 2669 if (FLAG_debug_code) { |
| 2670 __ Abort("StringCharCodeAt: out of bounds index."); |
| 2671 } |
| 2672 // No code needs to be generated. |
| 2673 return; |
| 2674 } |
| 2675 } else { |
| 2676 index = ToRegister(instr->index()); |
| 2677 } |
| 2678 Register result = ToRegister(instr->result()); |
| 2679 |
| 2680 DeferredStringCharCodeAt* deferred = |
| 2681 new DeferredStringCharCodeAt(this, instr); |
| 2682 |
| 2683 NearLabel flat_string, ascii_string, done; |
| 2684 |
| 2685 // Fetch the instance type of the receiver into result register. |
| 2686 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); |
| 2687 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
| 2688 |
| 2689 // We need special handling for non-flat strings. |
| 2690 STATIC_ASSERT(kSeqStringTag == 0); |
| 2691 __ test(result, Immediate(kStringRepresentationMask)); |
| 2692 __ j(zero, &flat_string); |
| 2693 |
| 2694 // Handle non-flat strings. |
| 2695 __ test(result, Immediate(kIsConsStringMask)); |
| 2696 __ j(zero, deferred->entry()); |
| 2697 |
| 2698 // ConsString. |
| 2699 // Check whether the right hand side is the empty string (i.e. if |
| 2700 // this is really a flat string in a cons string). If that is not |
| 2701 // the case we would rather go to the runtime system now to flatten |
| 2702 // the string. |
| 2703 __ cmp(FieldOperand(string, ConsString::kSecondOffset), |
| 2704 Immediate(Factory::empty_string())); |
| 2705 __ j(not_equal, deferred->entry()); |
| 2706 // Get the first of the two strings and load its instance type. |
| 2707 __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); |
| 2708 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); |
| 2709 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
| 2710 // If the first cons component is also non-flat, then go to runtime. |
| 2711 STATIC_ASSERT(kSeqStringTag == 0); |
| 2712 __ test(result, Immediate(kStringRepresentationMask)); |
| 2713 __ j(not_zero, deferred->entry()); |
| 2714 |
| 2715 // Check for 1-byte or 2-byte string. |
| 2716 __ bind(&flat_string); |
| 2717 STATIC_ASSERT(kAsciiStringTag != 0); |
| 2718 __ test(result, Immediate(kStringEncodingMask)); |
| 2719 __ j(not_zero, &ascii_string); |
| 2720 |
| 2721 // 2-byte string. |
| 2722 // Load the 2-byte character code into the result register. |
| 2723 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
| 2724 if (instr->index()->IsConstantOperand()) { |
| 2725 __ movzx_w(result, |
| 2726 FieldOperand(string, |
| 2727 SeqTwoByteString::kHeaderSize + 2 * const_index)); |
| 2728 } else { |
| 2729 __ movzx_w(result, FieldOperand(string, |
| 2730 index, |
| 2731 times_2, |
| 2732 SeqTwoByteString::kHeaderSize)); |
| 2733 } |
| 2734 __ jmp(&done); |
| 2735 |
| 2736 // ASCII string. |
| 2737 // Load the byte into the result register. |
| 2738 __ bind(&ascii_string); |
| 2739 if (instr->index()->IsConstantOperand()) { |
| 2740 __ movzx_b(result, FieldOperand(string, |
| 2741 SeqAsciiString::kHeaderSize + const_index)); |
| 2742 } else { |
| 2743 __ movzx_b(result, FieldOperand(string, |
| 2744 index, |
| 2745 times_1, |
| 2746 SeqAsciiString::kHeaderSize)); |
| 2747 } |
| 2748 __ bind(&done); |
| 2749 __ bind(deferred->exit()); |
| 2750 } |
| 2751 |
| 2752 |
| 2753 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { |
| 2754 Register string = ToRegister(instr->string()); |
| 2755 Register result = ToRegister(instr->result()); |
| 2756 |
| 2757 // TODO(3095996): Get rid of this. For now, we need to make the |
| 2758 // result register contain a valid pointer because it is already |
| 2759 // contained in the register pointer map. |
| 2760 __ Set(result, Immediate(0)); |
| 2761 |
| 2762 __ PushSafepointRegisters(); |
| 2763 __ push(string); |
| 2764 // Push the index as a smi. This is safe because of the checks in |
| 2765 // DoStringCharCodeAt above. |
| 2766 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); |
| 2767 if (instr->index()->IsConstantOperand()) { |
| 2768 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
| 2769 __ push(Immediate(Smi::FromInt(const_index))); |
| 2770 } else { |
| 2771 Register index = ToRegister(instr->index()); |
| 2772 __ SmiTag(index); |
| 2773 __ push(index); |
| 2774 } |
| 2775 __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt); |
| 2776 RecordSafepointWithRegisters( |
| 2777 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex); |
| 2778 if (FLAG_debug_code) { |
| 2779 __ AbortIfNotSmi(eax); |
| 2780 } |
| 2781 __ SmiUntag(eax); |
| 2782 __ mov(Operand(esp, EspIndexForPushAll(result) * kPointerSize), eax); |
| 2783 __ PopSafepointRegisters(); |
| 2784 } |
| 2785 |
| 2786 |
| 2787 void LCodeGen::DoStringLength(LStringLength* instr) { |
| 2788 Register string = ToRegister(instr->string()); |
| 2789 Register result = ToRegister(instr->result()); |
| 2790 __ mov(result, FieldOperand(string, String::kLengthOffset)); |
| 2791 } |
| 2792 |
| 2793 |
| 2654 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 2794 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 2655 LOperand* input = instr->InputAt(0); | 2795 LOperand* input = instr->InputAt(0); |
| 2656 ASSERT(input->IsRegister() || input->IsStackSlot()); | 2796 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 2657 LOperand* output = instr->result(); | 2797 LOperand* output = instr->result(); |
| 2658 ASSERT(output->IsDoubleRegister()); | 2798 ASSERT(output->IsDoubleRegister()); |
| 2659 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); | 2799 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); |
| 2660 } | 2800 } |
| 2661 | 2801 |
| 2662 | 2802 |
| 2663 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 2803 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3070 } | 3210 } |
| 3071 | 3211 |
| 3072 | 3212 |
| 3073 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 3213 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
| 3074 Register input = ToRegister(instr->InputAt(0)); | 3214 Register input = ToRegister(instr->InputAt(0)); |
| 3075 Register temp = ToRegister(instr->TempAt(0)); | 3215 Register temp = ToRegister(instr->TempAt(0)); |
| 3076 InstanceType first = instr->hydrogen()->first(); | 3216 InstanceType first = instr->hydrogen()->first(); |
| 3077 InstanceType last = instr->hydrogen()->last(); | 3217 InstanceType last = instr->hydrogen()->last(); |
| 3078 | 3218 |
| 3079 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); | 3219 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); |
| 3080 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), | |
| 3081 static_cast<int8_t>(first)); | |
| 3082 | 3220 |
| 3083 // If there is only one type in the interval check for equality. | 3221 // If there is only one type in the interval check for equality. |
| 3084 if (first == last) { | 3222 if (first == last) { |
| 3223 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), |
| 3224 static_cast<int8_t>(first)); |
| 3085 DeoptimizeIf(not_equal, instr->environment()); | 3225 DeoptimizeIf(not_equal, instr->environment()); |
| 3086 } else { | 3226 } else if (first == FIRST_STRING_TYPE && last == LAST_STRING_TYPE) { |
| 3227 // String has a dedicated bit in instance type. |
| 3228 __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), kIsNotStringMask); |
| 3229 DeoptimizeIf(not_zero, instr->environment()); |
| 3230 } else { |
| 3231 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), |
| 3232 static_cast<int8_t>(first)); |
| 3087 DeoptimizeIf(below, instr->environment()); | 3233 DeoptimizeIf(below, instr->environment()); |
| 3088 // Omit check for the last type. | 3234 // Omit check for the last type. |
| 3089 if (last != LAST_TYPE) { | 3235 if (last != LAST_TYPE) { |
| 3090 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), | 3236 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), |
| 3091 static_cast<int8_t>(last)); | 3237 static_cast<int8_t>(last)); |
| 3092 DeoptimizeIf(above, instr->environment()); | 3238 DeoptimizeIf(above, instr->environment()); |
| 3093 } | 3239 } |
| 3094 } | 3240 } |
| 3095 } | 3241 } |
| 3096 | 3242 |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3285 Label true_label; | 3431 Label true_label; |
| 3286 Label false_label; | 3432 Label false_label; |
| 3287 NearLabel done; | 3433 NearLabel done; |
| 3288 | 3434 |
| 3289 Condition final_branch_condition = EmitTypeofIs(&true_label, | 3435 Condition final_branch_condition = EmitTypeofIs(&true_label, |
| 3290 &false_label, | 3436 &false_label, |
| 3291 input, | 3437 input, |
| 3292 instr->type_literal()); | 3438 instr->type_literal()); |
| 3293 __ j(final_branch_condition, &true_label); | 3439 __ j(final_branch_condition, &true_label); |
| 3294 __ bind(&false_label); | 3440 __ bind(&false_label); |
| 3295 __ mov(result, Handle<Object>(Heap::false_value())); | 3441 __ mov(result, Factory::false_value()); |
| 3296 __ jmp(&done); | 3442 __ jmp(&done); |
| 3297 | 3443 |
| 3298 __ bind(&true_label); | 3444 __ bind(&true_label); |
| 3299 __ mov(result, Handle<Object>(Heap::true_value())); | 3445 __ mov(result, Factory::true_value()); |
| 3300 | 3446 |
| 3301 __ bind(&done); | 3447 __ bind(&done); |
| 3302 } | 3448 } |
| 3303 | 3449 |
| 3304 | 3450 |
| 3305 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 3451 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 3306 Register input = ToRegister(instr->InputAt(0)); | 3452 Register input = ToRegister(instr->InputAt(0)); |
| 3307 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 3453 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 3308 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 3454 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 3309 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 3455 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3334 __ test(input, Immediate(kSmiTagMask)); | 3480 __ test(input, Immediate(kSmiTagMask)); |
| 3335 __ j(zero, false_label); | 3481 __ j(zero, false_label); |
| 3336 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 3482 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
| 3337 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 3483 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| 3338 1 << Map::kIsUndetectable); | 3484 1 << Map::kIsUndetectable); |
| 3339 __ j(not_zero, false_label); | 3485 __ j(not_zero, false_label); |
| 3340 __ CmpInstanceType(input, FIRST_NONSTRING_TYPE); | 3486 __ CmpInstanceType(input, FIRST_NONSTRING_TYPE); |
| 3341 final_branch_condition = below; | 3487 final_branch_condition = below; |
| 3342 | 3488 |
| 3343 } else if (type_name->Equals(Heap::boolean_symbol())) { | 3489 } else if (type_name->Equals(Heap::boolean_symbol())) { |
| 3344 __ cmp(input, Handle<Object>(Heap::true_value())); | 3490 __ cmp(input, Factory::true_value()); |
| 3345 __ j(equal, true_label); | 3491 __ j(equal, true_label); |
| 3346 __ cmp(input, Handle<Object>(Heap::false_value())); | 3492 __ cmp(input, Factory::false_value()); |
| 3347 final_branch_condition = equal; | 3493 final_branch_condition = equal; |
| 3348 | 3494 |
| 3349 } else if (type_name->Equals(Heap::undefined_symbol())) { | 3495 } else if (type_name->Equals(Heap::undefined_symbol())) { |
| 3350 __ cmp(input, Factory::undefined_value()); | 3496 __ cmp(input, Factory::undefined_value()); |
| 3351 __ j(equal, true_label); | 3497 __ j(equal, true_label); |
| 3352 __ test(input, Immediate(kSmiTagMask)); | 3498 __ test(input, Immediate(kSmiTagMask)); |
| 3353 __ j(zero, false_label); | 3499 __ j(zero, false_label); |
| 3354 // Check for undetectable objects => true. | 3500 // Check for undetectable objects => true. |
| 3355 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); | 3501 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); |
| 3356 __ test_b(FieldOperand(input, Map::kBitFieldOffset), | 3502 __ test_b(FieldOperand(input, Map::kBitFieldOffset), |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3450 ASSERT(osr_pc_offset_ == -1); | 3596 ASSERT(osr_pc_offset_ == -1); |
| 3451 osr_pc_offset_ = masm()->pc_offset(); | 3597 osr_pc_offset_ = masm()->pc_offset(); |
| 3452 } | 3598 } |
| 3453 | 3599 |
| 3454 | 3600 |
| 3455 #undef __ | 3601 #undef __ |
| 3456 | 3602 |
| 3457 } } // namespace v8::internal | 3603 } } // namespace v8::internal |
| 3458 | 3604 |
| 3459 #endif // V8_TARGET_ARCH_IA32 | 3605 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |