| 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 | 181 |
| 182 // Deferred code is the last part of the instruction sequence. Mark | 182 // Deferred code is the last part of the instruction sequence. Mark |
| 183 // the generated code as done unless we bailed out. | 183 // the generated code as done unless we bailed out. |
| 184 if (!is_aborted()) status_ = DONE; | 184 if (!is_aborted()) status_ = DONE; |
| 185 return !is_aborted(); | 185 return !is_aborted(); |
| 186 } | 186 } |
| 187 | 187 |
| 188 | 188 |
| 189 bool LCodeGen::GenerateSafepointTable() { | 189 bool LCodeGen::GenerateSafepointTable() { |
| 190 ASSERT(is_done()); | 190 ASSERT(is_done()); |
| 191 // Ensure that patching a deoptimization point won't overwrite the table. |
| 192 for (int i = 0; i < Assembler::kCallInstructionLength; i++) { |
| 193 masm()->int3(); |
| 194 } |
| 191 safepoints_.Emit(masm(), StackSlotCount()); | 195 safepoints_.Emit(masm(), StackSlotCount()); |
| 192 return !is_aborted(); | 196 return !is_aborted(); |
| 193 } | 197 } |
| 194 | 198 |
| 195 | 199 |
| 196 Register LCodeGen::ToRegister(int index) const { | 200 Register LCodeGen::ToRegister(int index) const { |
| 197 return Register::FromAllocationIndex(index); | 201 return Register::FromAllocationIndex(index); |
| 198 } | 202 } |
| 199 | 203 |
| 200 | 204 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 translation->StoreLiteral(src_index); | 339 translation->StoreLiteral(src_index); |
| 336 } else { | 340 } else { |
| 337 UNREACHABLE(); | 341 UNREACHABLE(); |
| 338 } | 342 } |
| 339 } | 343 } |
| 340 | 344 |
| 341 | 345 |
| 342 void LCodeGen::CallCode(Handle<Code> code, | 346 void LCodeGen::CallCode(Handle<Code> code, |
| 343 RelocInfo::Mode mode, | 347 RelocInfo::Mode mode, |
| 344 LInstruction* instr) { | 348 LInstruction* instr) { |
| 345 if (instr != NULL) { | 349 ASSERT(instr != NULL); |
| 346 LPointerMap* pointers = instr->pointer_map(); | 350 LPointerMap* pointers = instr->pointer_map(); |
| 347 RecordPosition(pointers->position()); | 351 RecordPosition(pointers->position()); |
| 348 __ call(code, mode); | 352 __ call(code, mode); |
| 349 RegisterLazyDeoptimization(instr); | 353 RegisterLazyDeoptimization(instr); |
| 350 } else { | |
| 351 LPointerMap no_pointers(0); | |
| 352 RecordPosition(no_pointers.position()); | |
| 353 __ call(code, mode); | |
| 354 RecordSafepoint(&no_pointers, Safepoint::kNoDeoptimizationIndex); | |
| 355 } | |
| 356 | 354 |
| 357 // Signal that we don't inline smi code before these stubs in the | 355 // Signal that we don't inline smi code before these stubs in the |
| 358 // optimizing code generator. | 356 // optimizing code generator. |
| 359 if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC || | 357 if (code->kind() == Code::TYPE_RECORDING_BINARY_OP_IC || |
| 360 code->kind() == Code::COMPARE_IC) { | 358 code->kind() == Code::COMPARE_IC) { |
| 361 __ nop(); | 359 __ nop(); |
| 362 } | 360 } |
| 363 } | 361 } |
| 364 | 362 |
| 365 | 363 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 for (int i = 0, length = inlined_closures->length(); | 486 for (int i = 0, length = inlined_closures->length(); |
| 489 i < length; | 487 i < length; |
| 490 i++) { | 488 i++) { |
| 491 DefineDeoptimizationLiteral(inlined_closures->at(i)); | 489 DefineDeoptimizationLiteral(inlined_closures->at(i)); |
| 492 } | 490 } |
| 493 | 491 |
| 494 inlined_function_count_ = deoptimization_literals_.length(); | 492 inlined_function_count_ = deoptimization_literals_.length(); |
| 495 } | 493 } |
| 496 | 494 |
| 497 | 495 |
| 496 void LCodeGen::RecordSafepoint( |
| 497 LPointerMap* pointers, |
| 498 Safepoint::Kind kind, |
| 499 int arguments, |
| 500 int deoptimization_index) { |
| 501 const ZoneList<LOperand*>* operands = pointers->operands(); |
| 502 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), |
| 503 kind, arguments, deoptimization_index); |
| 504 for (int i = 0; i < operands->length(); i++) { |
| 505 LOperand* pointer = operands->at(i); |
| 506 if (pointer->IsStackSlot()) { |
| 507 safepoint.DefinePointerSlot(pointer->index()); |
| 508 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { |
| 509 safepoint.DefinePointerRegister(ToRegister(pointer)); |
| 510 } |
| 511 } |
| 512 if (kind & Safepoint::kWithRegisters) { |
| 513 // Register rsi always contains a pointer to the context. |
| 514 safepoint.DefinePointerRegister(rsi); |
| 515 } |
| 516 } |
| 517 |
| 518 |
| 498 void LCodeGen::RecordSafepoint(LPointerMap* pointers, | 519 void LCodeGen::RecordSafepoint(LPointerMap* pointers, |
| 499 int deoptimization_index) { | 520 int deoptimization_index) { |
| 500 const ZoneList<LOperand*>* operands = pointers->operands(); | 521 RecordSafepoint(pointers, Safepoint::kSimple, 0, deoptimization_index); |
| 501 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), | |
| 502 deoptimization_index); | |
| 503 for (int i = 0; i < operands->length(); i++) { | |
| 504 LOperand* pointer = operands->at(i); | |
| 505 if (pointer->IsStackSlot()) { | |
| 506 safepoint.DefinePointerSlot(pointer->index()); | |
| 507 } | |
| 508 } | |
| 509 } | 522 } |
| 510 | 523 |
| 511 | 524 |
| 512 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, | 525 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, |
| 513 int arguments, | 526 int arguments, |
| 514 int deoptimization_index) { | 527 int deoptimization_index) { |
| 515 const ZoneList<LOperand*>* operands = pointers->operands(); | 528 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, |
| 516 Safepoint safepoint = | 529 deoptimization_index); |
| 517 safepoints_.DefineSafepointWithRegisters( | |
| 518 masm(), arguments, deoptimization_index); | |
| 519 for (int i = 0; i < operands->length(); i++) { | |
| 520 LOperand* pointer = operands->at(i); | |
| 521 if (pointer->IsStackSlot()) { | |
| 522 safepoint.DefinePointerSlot(pointer->index()); | |
| 523 } else if (pointer->IsRegister()) { | |
| 524 safepoint.DefinePointerRegister(ToRegister(pointer)); | |
| 525 } | |
| 526 } | |
| 527 // Register rsi always contains a pointer to the context. | |
| 528 safepoint.DefinePointerRegister(rsi); | |
| 529 } | 530 } |
| 530 | 531 |
| 531 | 532 |
| 532 void LCodeGen::RecordPosition(int position) { | 533 void LCodeGen::RecordPosition(int position) { |
| 533 if (!FLAG_debug_info || position == RelocInfo::kNoPosition) return; | 534 if (!FLAG_debug_info || position == RelocInfo::kNoPosition) return; |
| 534 masm()->positions_recorder()->RecordPosition(position); | 535 masm()->positions_recorder()->RecordPosition(position); |
| 535 } | 536 } |
| 536 | 537 |
| 537 | 538 |
| 538 void LCodeGen::DoLabel(LLabel* label) { | 539 void LCodeGen::DoLabel(LLabel* label) { |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 __ push(rax); | 1382 __ push(rax); |
| 1382 __ CallRuntime(Runtime::kTraceExit, 1); | 1383 __ CallRuntime(Runtime::kTraceExit, 1); |
| 1383 } | 1384 } |
| 1384 __ movq(rsp, rbp); | 1385 __ movq(rsp, rbp); |
| 1385 __ pop(rbp); | 1386 __ pop(rbp); |
| 1386 __ ret((ParameterCount() + 1) * kPointerSize); | 1387 __ ret((ParameterCount() + 1) * kPointerSize); |
| 1387 } | 1388 } |
| 1388 | 1389 |
| 1389 | 1390 |
| 1390 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { | 1391 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { |
| 1391 Abort("Unimplemented: %s", "DoLoadGlobal"); | 1392 Register result = ToRegister(instr->result()); |
| 1393 if (result.is(rax)) { |
| 1394 __ load_rax(instr->hydrogen()->cell().location(), |
| 1395 RelocInfo::GLOBAL_PROPERTY_CELL); |
| 1396 } else { |
| 1397 __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL); |
| 1398 __ movq(result, Operand(result, 0)); |
| 1399 } |
| 1400 if (instr->hydrogen()->check_hole_value()) { |
| 1401 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
| 1402 DeoptimizeIf(equal, instr->environment()); |
| 1403 } |
| 1392 } | 1404 } |
| 1393 | 1405 |
| 1394 | 1406 |
| 1395 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { | 1407 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { |
| 1396 Abort("Unimplemented: %s", "DoStoreGlobal"); | 1408 Register value = ToRegister(instr->InputAt(0)); |
| 1409 if (value.is(rax)) { |
| 1410 __ store_rax(instr->hydrogen()->cell().location(), |
| 1411 RelocInfo::GLOBAL_PROPERTY_CELL); |
| 1412 } else { |
| 1413 __ movq(kScratchRegister, |
| 1414 Handle<Object>::cast(instr->hydrogen()->cell()), |
| 1415 RelocInfo::GLOBAL_PROPERTY_CELL); |
| 1416 __ movq(Operand(kScratchRegister, 0), value); |
| 1417 } |
| 1397 } | 1418 } |
| 1398 | 1419 |
| 1399 | 1420 |
| 1400 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 1421 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 1401 Abort("Unimplemented: %s", "DoLoadContextSlot"); | 1422 Abort("Unimplemented: %s", "DoLoadContextSlot"); |
| 1402 } | 1423 } |
| 1403 | 1424 |
| 1404 | 1425 |
| 1405 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 1426 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
| 1406 Abort("Unimplemented: %s", "DoLoadNamedField"); | 1427 Register object = ToRegister(instr->InputAt(0)); |
| 1428 Register result = ToRegister(instr->result()); |
| 1429 if (instr->hydrogen()->is_in_object()) { |
| 1430 __ movq(result, FieldOperand(object, instr->hydrogen()->offset())); |
| 1431 } else { |
| 1432 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 1433 __ movq(result, FieldOperand(result, instr->hydrogen()->offset())); |
| 1434 } |
| 1407 } | 1435 } |
| 1408 | 1436 |
| 1409 | 1437 |
| 1410 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 1438 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 1411 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); | 1439 Abort("Unimplemented: %s", "DoLoadNamedGeneric"); |
| 1412 } | 1440 } |
| 1413 | 1441 |
| 1414 | 1442 |
| 1415 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { | 1443 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| 1416 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); | 1444 Abort("Unimplemented: %s", "DoLoadFunctionPrototype"); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1446 Abort("Unimplemented: %s", "DoArgumentsLength"); | 1474 Abort("Unimplemented: %s", "DoArgumentsLength"); |
| 1447 } | 1475 } |
| 1448 | 1476 |
| 1449 | 1477 |
| 1450 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { | 1478 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
| 1451 Abort("Unimplemented: %s", "DoApplyArguments"); | 1479 Abort("Unimplemented: %s", "DoApplyArguments"); |
| 1452 } | 1480 } |
| 1453 | 1481 |
| 1454 | 1482 |
| 1455 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 1483 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
| 1456 Abort("Unimplemented: %s", "DoPushArgument"); | 1484 LOperand* argument = instr->InputAt(0); |
| 1485 if (argument->IsConstantOperand()) { |
| 1486 LConstantOperand* const_op = LConstantOperand::cast(argument); |
| 1487 Handle<Object> literal = chunk_->LookupLiteral(const_op); |
| 1488 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 1489 if (r.IsInteger32()) { |
| 1490 ASSERT(literal->IsNumber()); |
| 1491 __ push(Immediate(static_cast<int32_t>(literal->Number()))); |
| 1492 } else if (r.IsDouble()) { |
| 1493 Abort("unsupported double immediate"); |
| 1494 } else { |
| 1495 ASSERT(r.IsTagged()); |
| 1496 __ Push(literal); |
| 1497 } |
| 1498 } else if (argument->IsRegister()) { |
| 1499 __ push(ToRegister(argument)); |
| 1500 } else { |
| 1501 ASSERT(!argument->IsDoubleRegister()); |
| 1502 __ push(ToOperand(argument)); |
| 1503 } |
| 1457 } | 1504 } |
| 1458 | 1505 |
| 1459 | 1506 |
| 1460 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { | 1507 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { |
| 1461 Register result = ToRegister(instr->result()); | 1508 Register result = ToRegister(instr->result()); |
| 1462 __ movq(result, GlobalObjectOperand()); | 1509 __ movq(result, GlobalObjectOperand()); |
| 1463 } | 1510 } |
| 1464 | 1511 |
| 1465 | 1512 |
| 1466 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 1513 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
| 1467 Abort("Unimplemented: %s", "DoGlobalReceiver"); | 1514 Register result = ToRegister(instr->result()); |
| 1515 __ movq(result, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 1516 __ movq(result, FieldOperand(result, GlobalObject::kGlobalReceiverOffset)); |
| 1468 } | 1517 } |
| 1469 | 1518 |
| 1470 | 1519 |
| 1471 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 1520 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
| 1472 int arity, | 1521 int arity, |
| 1473 LInstruction* instr) { | 1522 LInstruction* instr) { |
| 1474 Abort("Unimplemented: %s", "CallKnownFunction"); | 1523 Abort("Unimplemented: %s", "CallKnownFunction"); |
| 1475 } | 1524 } |
| 1476 | 1525 |
| 1477 | 1526 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1554 Abort("Unimplemented: %s", "DoCallGlobal"); | 1603 Abort("Unimplemented: %s", "DoCallGlobal"); |
| 1555 } | 1604 } |
| 1556 | 1605 |
| 1557 | 1606 |
| 1558 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 1607 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
| 1559 Abort("Unimplemented: %s", "DoCallKnownGlobal"); | 1608 Abort("Unimplemented: %s", "DoCallKnownGlobal"); |
| 1560 } | 1609 } |
| 1561 | 1610 |
| 1562 | 1611 |
| 1563 void LCodeGen::DoCallNew(LCallNew* instr) { | 1612 void LCodeGen::DoCallNew(LCallNew* instr) { |
| 1564 Abort("Unimplemented: %s", "DoCallNew"); | 1613 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); |
| 1614 ASSERT(ToRegister(instr->result()).is(rax)); |
| 1615 |
| 1616 Handle<Code> builtin(Isolate::Current()->builtins()->builtin( |
| 1617 Builtins::JSConstructCall)); |
| 1618 __ Set(rax, instr->arity()); |
| 1619 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); |
| 1565 } | 1620 } |
| 1566 | 1621 |
| 1567 | 1622 |
| 1568 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 1623 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
| 1569 Abort("Unimplemented: %s", "DoCallRuntime"); | 1624 Abort("Unimplemented: %s", "DoCallRuntime"); |
| 1570 } | 1625 } |
| 1571 | 1626 |
| 1572 | 1627 |
| 1573 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 1628 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 1574 Abort("Unimplemented: %s", "DoStoreNamedField"); | 1629 Register object = ToRegister(instr->object()); |
| 1630 Register value = ToRegister(instr->value()); |
| 1631 int offset = instr->offset(); |
| 1632 |
| 1633 if (!instr->transition().is_null()) { |
| 1634 __ Move(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); |
| 1635 } |
| 1636 |
| 1637 // Do the store. |
| 1638 if (instr->is_in_object()) { |
| 1639 __ movq(FieldOperand(object, offset), value); |
| 1640 if (instr->needs_write_barrier()) { |
| 1641 Register temp = ToRegister(instr->TempAt(0)); |
| 1642 // Update the write barrier for the object for in-object properties. |
| 1643 __ RecordWrite(object, offset, value, temp); |
| 1644 } |
| 1645 } else { |
| 1646 Register temp = ToRegister(instr->TempAt(0)); |
| 1647 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 1648 __ movq(FieldOperand(temp, offset), value); |
| 1649 if (instr->needs_write_barrier()) { |
| 1650 // Update the write barrier for the properties array. |
| 1651 // object is used as a scratch register. |
| 1652 __ RecordWrite(temp, offset, value, object); |
| 1653 } |
| 1654 } |
| 1575 } | 1655 } |
| 1576 | 1656 |
| 1577 | 1657 |
| 1578 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 1658 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 1579 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); | 1659 Abort("Unimplemented: %s", "DoStoreNamedGeneric"); |
| 1580 } | 1660 } |
| 1581 | 1661 |
| 1582 | 1662 |
| 1583 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { | 1663 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
| 1584 Abort("Unimplemented: %s", "DoBoundsCheck"); | 1664 Abort("Unimplemented: %s", "DoBoundsCheck"); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1714 Abort("Unimplemented: %s", "DoNumberUntagD"); | 1794 Abort("Unimplemented: %s", "DoNumberUntagD"); |
| 1715 } | 1795 } |
| 1716 | 1796 |
| 1717 | 1797 |
| 1718 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 1798 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
| 1719 Abort("Unimplemented: %s", "DoDoubleToI"); | 1799 Abort("Unimplemented: %s", "DoDoubleToI"); |
| 1720 } | 1800 } |
| 1721 | 1801 |
| 1722 | 1802 |
| 1723 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 1803 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 1724 Abort("Unimplemented: %s", "DoCheckSmi"); | 1804 LOperand* input = instr->InputAt(0); |
| 1805 ASSERT(input->IsRegister()); |
| 1806 Condition cc = masm()->CheckSmi(ToRegister(input)); |
| 1807 if (instr->condition() != equal) { |
| 1808 cc = NegateCondition(cc); |
| 1809 } |
| 1810 DeoptimizeIf(cc, instr->environment()); |
| 1725 } | 1811 } |
| 1726 | 1812 |
| 1727 | 1813 |
| 1728 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 1814 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
| 1729 Abort("Unimplemented: %s", "DoCheckInstanceType"); | 1815 Abort("Unimplemented: %s", "DoCheckInstanceType"); |
| 1730 } | 1816 } |
| 1731 | 1817 |
| 1732 | 1818 |
| 1733 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 1819 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 1734 Abort("Unimplemented: %s", "DoCheckFunction"); | 1820 ASSERT(instr->InputAt(0)->IsRegister()); |
| 1821 Register reg = ToRegister(instr->InputAt(0)); |
| 1822 __ Cmp(reg, instr->hydrogen()->target()); |
| 1823 DeoptimizeIf(not_equal, instr->environment()); |
| 1735 } | 1824 } |
| 1736 | 1825 |
| 1737 | 1826 |
| 1738 void LCodeGen::DoCheckMap(LCheckMap* instr) { | 1827 void LCodeGen::DoCheckMap(LCheckMap* instr) { |
| 1739 Abort("Unimplemented: %s", "DoCheckMap"); | 1828 LOperand* input = instr->InputAt(0); |
| 1829 ASSERT(input->IsRegister()); |
| 1830 Register reg = ToRegister(input); |
| 1831 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1832 instr->hydrogen()->map()); |
| 1833 DeoptimizeIf(not_equal, instr->environment()); |
| 1740 } | 1834 } |
| 1741 | 1835 |
| 1742 | 1836 |
| 1743 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { | 1837 void LCodeGen::LoadHeapObject(Register result, Handle<HeapObject> object) { |
| 1744 Abort("Unimplemented: %s", "LoadHeapObject"); | 1838 Abort("Unimplemented: %s", "LoadHeapObject"); |
| 1745 } | 1839 } |
| 1746 | 1840 |
| 1747 | 1841 |
| 1748 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { | 1842 void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { |
| 1749 Abort("Unimplemented: %s", "DoCheckPrototypeMaps"); | 1843 Register reg = ToRegister(instr->TempAt(0)); |
| 1844 |
| 1845 Handle<JSObject> holder = instr->holder(); |
| 1846 Handle<JSObject> current_prototype = instr->prototype(); |
| 1847 |
| 1848 // Load prototype object. |
| 1849 LoadHeapObject(reg, current_prototype); |
| 1850 |
| 1851 // Check prototype maps up to the holder. |
| 1852 while (!current_prototype.is_identical_to(holder)) { |
| 1853 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1854 Handle<Map>(current_prototype->map())); |
| 1855 DeoptimizeIf(not_equal, instr->environment()); |
| 1856 current_prototype = |
| 1857 Handle<JSObject>(JSObject::cast(current_prototype->GetPrototype())); |
| 1858 // Load next prototype object. |
| 1859 LoadHeapObject(reg, current_prototype); |
| 1860 } |
| 1861 |
| 1862 // Check the holder map. |
| 1863 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1864 Handle<Map>(current_prototype->map())); |
| 1865 DeoptimizeIf(not_equal, instr->environment()); |
| 1750 } | 1866 } |
| 1751 | 1867 |
| 1752 | 1868 |
| 1753 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 1869 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| 1754 Abort("Unimplemented: %s", "DoArrayLiteral"); | 1870 Abort("Unimplemented: %s", "DoArrayLiteral"); |
| 1755 } | 1871 } |
| 1756 | 1872 |
| 1757 | 1873 |
| 1758 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 1874 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
| 1759 Abort("Unimplemented: %s", "DoObjectLiteral"); | 1875 Abort("Unimplemented: %s", "DoObjectLiteral"); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1891 | 2007 |
| 1892 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 2008 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
| 1893 Abort("Unimplemented: %s", "DoOsrEntry"); | 2009 Abort("Unimplemented: %s", "DoOsrEntry"); |
| 1894 } | 2010 } |
| 1895 | 2011 |
| 1896 #undef __ | 2012 #undef __ |
| 1897 | 2013 |
| 1898 } } // namespace v8::internal | 2014 } } // namespace v8::internal |
| 1899 | 2015 |
| 1900 #endif // V8_TARGET_ARCH_X64 | 2016 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |