OLD | NEW |
1 // Copyright 2012 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 |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 HBasicBlock* next = NULL; | 480 HBasicBlock* next = NULL; |
481 if (i < blocks->length() - 1) next = blocks->at(i + 1); | 481 if (i < blocks->length() - 1) next = blocks->at(i + 1); |
482 DoBasicBlock(blocks->at(i), next); | 482 DoBasicBlock(blocks->at(i), next); |
483 if (is_aborted()) return NULL; | 483 if (is_aborted()) return NULL; |
484 } | 484 } |
485 status_ = DONE; | 485 status_ = DONE; |
486 return chunk_; | 486 return chunk_; |
487 } | 487 } |
488 | 488 |
489 | 489 |
490 void LChunkBuilder::Abort(BailoutReason reason) { | 490 void LChunkBuilder::Abort(const char* reason) { |
491 info()->set_bailout_reason(reason); | 491 info()->set_bailout_reason(reason); |
492 status_ = ABORTED; | 492 status_ = ABORTED; |
493 } | 493 } |
494 | 494 |
495 | 495 |
496 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) { | 496 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) { |
497 return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER, | 497 return new(zone()) LUnallocated(LUnallocated::FIXED_REGISTER, |
498 Register::ToAllocationIndex(reg)); | 498 Register::ToAllocationIndex(reg)); |
499 } | 499 } |
500 | 500 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 instr->set_pointer_map(new(zone()) LPointerMap(position_, zone())); | 691 instr->set_pointer_map(new(zone()) LPointerMap(position_, zone())); |
692 return instr; | 692 return instr; |
693 } | 693 } |
694 | 694 |
695 | 695 |
696 LUnallocated* LChunkBuilder::TempRegister() { | 696 LUnallocated* LChunkBuilder::TempRegister() { |
697 LUnallocated* operand = | 697 LUnallocated* operand = |
698 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); | 698 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER); |
699 int vreg = allocator_->GetVirtualRegister(); | 699 int vreg = allocator_->GetVirtualRegister(); |
700 if (!allocator_->AllocationOk()) { | 700 if (!allocator_->AllocationOk()) { |
701 Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister); | 701 Abort("Out of virtual registers while trying to allocate temp register."); |
702 vreg = 0; | 702 vreg = 0; |
703 } | 703 } |
704 operand->set_virtual_register(vreg); | 704 operand->set_virtual_register(vreg); |
705 return operand; | 705 return operand; |
706 } | 706 } |
707 | 707 |
708 | 708 |
709 LOperand* LChunkBuilder::FixedTemp(Register reg) { | 709 LOperand* LChunkBuilder::FixedTemp(Register reg) { |
710 LUnallocated* operand = ToUnallocated(reg); | 710 LUnallocated* operand = ToUnallocated(reg); |
711 ASSERT(operand->HasFixedPolicy()); | 711 ASSERT(operand->HasFixedPolicy()); |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1407 LOperand* context = UseFixed(instr->context(), esi); | 1407 LOperand* context = UseFixed(instr->context(), esi); |
1408 LOperand* left = UseFixed(instr->left(), edx); | 1408 LOperand* left = UseFixed(instr->left(), edx); |
1409 LOperand* right = UseFixed(instr->right(), eax); | 1409 LOperand* right = UseFixed(instr->right(), eax); |
1410 LArithmeticT* result = | 1410 LArithmeticT* result = |
1411 new(zone()) LArithmeticT(instr->op(), context, left, right); | 1411 new(zone()) LArithmeticT(instr->op(), context, left, right); |
1412 return MarkAsCall(DefineFixed(result, eax), instr); | 1412 return MarkAsCall(DefineFixed(result, eax), instr); |
1413 } | 1413 } |
1414 } | 1414 } |
1415 | 1415 |
1416 | 1416 |
| 1417 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { |
| 1418 ASSERT(instr->value()->representation().IsInteger32()); |
| 1419 ASSERT(instr->representation().IsInteger32()); |
| 1420 if (instr->HasNoUses()) return NULL; |
| 1421 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1422 LBitNotI* result = new(zone()) LBitNotI(input); |
| 1423 return DefineSameAsFirst(result); |
| 1424 } |
| 1425 |
| 1426 |
1417 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1427 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1418 if (instr->representation().IsDouble()) { | 1428 if (instr->representation().IsDouble()) { |
1419 return DoArithmeticD(Token::DIV, instr); | 1429 return DoArithmeticD(Token::DIV, instr); |
1420 } else if (instr->representation().IsSmiOrInteger32()) { | 1430 } else if (instr->representation().IsSmiOrInteger32()) { |
1421 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1431 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1422 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1432 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1423 if (instr->HasPowerOf2Divisor()) { | 1433 if (instr->HasPowerOf2Divisor()) { |
1424 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1434 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
1425 LOperand* value = UseRegisterAtStart(instr->left()); | 1435 LOperand* value = UseRegisterAtStart(instr->left()); |
1426 LDivI* div = | 1436 LDivI* div = |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 LOperand* string = UseRegister(instr->string()); | 1844 LOperand* string = UseRegister(instr->string()); |
1835 LOperand* index = UseRegister(instr->index()); | 1845 LOperand* index = UseRegister(instr->index()); |
1836 ASSERT(ecx.is_byte_register()); | 1846 ASSERT(ecx.is_byte_register()); |
1837 LOperand* value = UseFixed(instr->value(), ecx); | 1847 LOperand* value = UseFixed(instr->value(), ecx); |
1838 LSeqStringSetChar* result = | 1848 LSeqStringSetChar* result = |
1839 new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); | 1849 new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); |
1840 return DefineSameAsFirst(result); | 1850 return DefineSameAsFirst(result); |
1841 } | 1851 } |
1842 | 1852 |
1843 | 1853 |
| 1854 LInstruction* LChunkBuilder::DoNumericConstraint(HNumericConstraint* instr) { |
| 1855 return NULL; |
| 1856 } |
| 1857 |
| 1858 |
| 1859 LInstruction* LChunkBuilder::DoInductionVariableAnnotation( |
| 1860 HInductionVariableAnnotation* instr) { |
| 1861 return NULL; |
| 1862 } |
| 1863 |
| 1864 |
1844 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1865 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
1845 return AssignEnvironment(new(zone()) LBoundsCheck( | 1866 return AssignEnvironment(new(zone()) LBoundsCheck( |
1846 UseRegisterOrConstantAtStart(instr->index()), | 1867 UseRegisterOrConstantAtStart(instr->index()), |
1847 UseAtStart(instr->length()))); | 1868 UseAtStart(instr->length()))); |
1848 } | 1869 } |
1849 | 1870 |
1850 | 1871 |
1851 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation( | 1872 LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation( |
1852 HBoundsCheckBaseIndexInformation* instr) { | 1873 HBoundsCheckBaseIndexInformation* instr) { |
1853 UNREACHABLE(); | 1874 UNREACHABLE(); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 | 2042 |
2022 | 2043 |
2023 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { | 2044 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { |
2024 LOperand* value = UseRegisterAtStart(instr->value()); | 2045 LOperand* value = UseRegisterAtStart(instr->value()); |
2025 LOperand* temp = TempRegister(); | 2046 LOperand* temp = TempRegister(); |
2026 LCheckInstanceType* result = new(zone()) LCheckInstanceType(value, temp); | 2047 LCheckInstanceType* result = new(zone()) LCheckInstanceType(value, temp); |
2027 return AssignEnvironment(result); | 2048 return AssignEnvironment(result); |
2028 } | 2049 } |
2029 | 2050 |
2030 | 2051 |
| 2052 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { |
| 2053 LUnallocated* temp = NULL; |
| 2054 if (!instr->CanOmitPrototypeChecks()) temp = TempRegister(); |
| 2055 LCheckPrototypeMaps* result = new(zone()) LCheckPrototypeMaps(temp); |
| 2056 if (instr->CanOmitPrototypeChecks()) return result; |
| 2057 return AssignEnvironment(result); |
| 2058 } |
| 2059 |
| 2060 |
2031 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { | 2061 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { |
2032 // If the target is in new space, we'll emit a global cell compare and so | 2062 // If the target is in new space, we'll emit a global cell compare and so |
2033 // want the value in a register. If the target gets promoted before we | 2063 // want the value in a register. If the target gets promoted before we |
2034 // emit code, we will still get the register but will do an immediate | 2064 // emit code, we will still get the register but will do an immediate |
2035 // compare instead of the cell compare. This is safe. | 2065 // compare instead of the cell compare. This is safe. |
2036 LOperand* value = instr->target_in_new_space() | 2066 LOperand* value = instr->target_in_new_space() |
2037 ? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value()); | 2067 ? UseRegisterAtStart(instr->value()) : UseAtStart(instr->value()); |
2038 return AssignEnvironment(new(zone()) LCheckFunction(value)); | 2068 return AssignEnvironment(new(zone()) LCheckFunction(value)); |
2039 } | 2069 } |
2040 | 2070 |
2041 | 2071 |
2042 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { | 2072 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { |
2043 LOperand* value = NULL; | 2073 LOperand* value = NULL; |
2044 if (!instr->CanOmitMapChecks()) { | 2074 if (!instr->CanOmitMapChecks()) value = UseRegisterAtStart(instr->value()); |
2045 value = UseRegisterAtStart(instr->value()); | |
2046 if (instr->has_migration_target()) info()->MarkAsDeferredCalling(); | |
2047 } | |
2048 LCheckMaps* result = new(zone()) LCheckMaps(value); | 2075 LCheckMaps* result = new(zone()) LCheckMaps(value); |
2049 if (!instr->CanOmitMapChecks()) { | 2076 if (instr->CanOmitMapChecks()) return result; |
2050 AssignEnvironment(result); | 2077 return AssignEnvironment(result); |
2051 if (instr->has_migration_target()) return AssignPointerMap(result); | |
2052 } | |
2053 return result; | |
2054 } | 2078 } |
2055 | 2079 |
2056 | 2080 |
2057 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { | 2081 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
2058 HValue* value = instr->value(); | 2082 HValue* value = instr->value(); |
2059 Representation input_rep = value->representation(); | 2083 Representation input_rep = value->representation(); |
2060 if (input_rep.IsDouble()) { | 2084 if (input_rep.IsDouble()) { |
2061 LOperand* reg = UseRegister(value); | 2085 LOperand* reg = UseRegister(value); |
2062 return DefineFixed(new(zone()) LClampDToUint8(reg), eax); | 2086 return DefineFixed(new(zone()) LClampDToUint8(reg), eax); |
2063 } else if (input_rep.IsInteger32()) { | 2087 } else if (input_rep.IsInteger32()) { |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2387 new(zone()) LTrapAllocationMemento(object, temp); | 2411 new(zone()) LTrapAllocationMemento(object, temp); |
2388 return AssignEnvironment(result); | 2412 return AssignEnvironment(result); |
2389 } | 2413 } |
2390 | 2414 |
2391 | 2415 |
2392 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 2416 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
2393 bool is_in_object = instr->access().IsInobject(); | 2417 bool is_in_object = instr->access().IsInobject(); |
2394 bool is_external_location = instr->access().IsExternalMemory() && | 2418 bool is_external_location = instr->access().IsExternalMemory() && |
2395 instr->access().offset() == 0; | 2419 instr->access().offset() == 0; |
2396 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 2420 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
2397 bool needs_write_barrier_for_map = instr->has_transition() && | 2421 bool needs_write_barrier_for_map = !instr->transition().is_null() && |
2398 instr->NeedsWriteBarrierForMap(); | 2422 instr->NeedsWriteBarrierForMap(); |
2399 | 2423 |
2400 LOperand* obj; | 2424 LOperand* obj; |
2401 if (needs_write_barrier) { | 2425 if (needs_write_barrier) { |
2402 obj = is_in_object | 2426 obj = is_in_object |
2403 ? UseRegister(instr->object()) | 2427 ? UseRegister(instr->object()) |
2404 : UseTempRegister(instr->object()); | 2428 : UseTempRegister(instr->object()); |
2405 } else if (is_external_location) { | 2429 } else if (is_external_location) { |
2406 ASSERT(!is_in_object); | 2430 ASSERT(!is_in_object); |
2407 ASSERT(!needs_write_barrier); | 2431 ASSERT(!needs_write_barrier); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2536 int index = static_cast<int>(instr->index()); | 2560 int index = static_cast<int>(instr->index()); |
2537 Register reg = DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index); | 2561 Register reg = DESCRIPTOR_GET_PARAMETER_REGISTER(descriptor, index); |
2538 return DefineFixed(result, reg); | 2562 return DefineFixed(result, reg); |
2539 } | 2563 } |
2540 } | 2564 } |
2541 | 2565 |
2542 | 2566 |
2543 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 2567 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
2544 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. | 2568 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. |
2545 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { | 2569 if (spill_index > LUnallocated::kMaxFixedSlotIndex) { |
2546 Abort(kTooManySpillSlotsNeededForOSR); | 2570 Abort("Too many spill slots needed for OSR"); |
2547 spill_index = 0; | 2571 spill_index = 0; |
2548 } | 2572 } |
2549 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); | 2573 return DefineAsSpilled(new(zone()) LUnknownOSRValue, spill_index); |
2550 } | 2574 } |
2551 | 2575 |
2552 | 2576 |
2553 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2577 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
2554 LOperand* context = UseFixed(instr->context(), esi); | 2578 LOperand* context = UseFixed(instr->context(), esi); |
2555 argument_count_ -= instr->argument_count(); | 2579 argument_count_ -= instr->argument_count(); |
2556 LCallStub* result = new(zone()) LCallStub(context); | 2580 LCallStub* result = new(zone()) LCallStub(context); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2721 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2745 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2722 LOperand* object = UseRegister(instr->object()); | 2746 LOperand* object = UseRegister(instr->object()); |
2723 LOperand* index = UseTempRegister(instr->index()); | 2747 LOperand* index = UseTempRegister(instr->index()); |
2724 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2748 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
2725 } | 2749 } |
2726 | 2750 |
2727 | 2751 |
2728 } } // namespace v8::internal | 2752 } } // namespace v8::internal |
2729 | 2753 |
2730 #endif // V8_TARGET_ARCH_IA32 | 2754 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |