| 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 |