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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 } | 701 } |
702 | 702 |
703 | 703 |
704 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 704 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
705 return AssignEnvironment(new(zone()) LDeoptimize); | 705 return AssignEnvironment(new(zone()) LDeoptimize); |
706 } | 706 } |
707 | 707 |
708 | 708 |
709 LInstruction* LChunkBuilder::DoShift(Token::Value op, | 709 LInstruction* LChunkBuilder::DoShift(Token::Value op, |
710 HBitwiseBinaryOperation* instr) { | 710 HBitwiseBinaryOperation* instr) { |
711 if (instr->representation().IsTagged()) { | 711 if (instr->representation().IsSmiOrTagged()) { |
712 ASSERT(instr->left()->representation().IsTagged()); | 712 ASSERT(instr->left()->representation().IsSmiOrTagged()); |
713 ASSERT(instr->right()->representation().IsTagged()); | 713 ASSERT(instr->right()->representation().IsSmiOrTagged()); |
714 | 714 |
715 LOperand* left = UseFixed(instr->left(), r1); | 715 LOperand* left = UseFixed(instr->left(), r1); |
716 LOperand* right = UseFixed(instr->right(), r0); | 716 LOperand* right = UseFixed(instr->right(), r0); |
717 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); | 717 LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); |
718 return MarkAsCall(DefineFixed(result, r0), instr); | 718 return MarkAsCall(DefineFixed(result, r0), instr); |
719 } | 719 } |
720 | 720 |
721 ASSERT(instr->representation().IsSmiOrInteger32()); | 721 ASSERT(instr->representation().IsInteger32()); |
722 ASSERT(instr->left()->representation().Equals(instr->representation())); | 722 ASSERT(instr->left()->representation().IsInteger32()); |
723 ASSERT(instr->right()->representation().Equals(instr->representation())); | 723 ASSERT(instr->right()->representation().IsInteger32()); |
724 LOperand* left = UseRegisterAtStart(instr->left()); | 724 LOperand* left = UseRegisterAtStart(instr->left()); |
725 | 725 |
726 HValue* right_value = instr->right(); | 726 HValue* right_value = instr->right(); |
727 LOperand* right = NULL; | 727 LOperand* right = NULL; |
728 int constant_value = 0; | 728 int constant_value = 0; |
729 bool does_deopt = false; | |
730 if (right_value->IsConstant()) { | 729 if (right_value->IsConstant()) { |
731 HConstant* constant = HConstant::cast(right_value); | 730 HConstant* constant = HConstant::cast(right_value); |
732 right = chunk_->DefineConstantOperand(constant); | 731 right = chunk_->DefineConstantOperand(constant); |
733 constant_value = constant->Integer32Value() & 0x1f; | 732 constant_value = constant->Integer32Value() & 0x1f; |
734 // Left shifts can deoptimize if we shift by > 0 and the result cannot be | |
735 // truncated to smi. | |
736 if (instr->representation().IsSmi() && constant_value > 0) { | |
737 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | |
738 if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) { | |
739 does_deopt = true; | |
740 break; | |
741 } | |
742 } | |
743 } | |
744 } else { | 733 } else { |
745 right = UseRegisterAtStart(right_value); | 734 right = UseRegisterAtStart(right_value); |
746 } | 735 } |
747 | 736 |
748 // Shift operations can only deoptimize if we do a logical shift | 737 // Shift operations can only deoptimize if we do a logical shift |
749 // by 0 and the result cannot be truncated to int32. | 738 // by 0 and the result cannot be truncated to int32. |
| 739 bool does_deopt = false; |
750 if (op == Token::SHR && constant_value == 0) { | 740 if (op == Token::SHR && constant_value == 0) { |
751 if (FLAG_opt_safe_uint32_operations) { | 741 if (FLAG_opt_safe_uint32_operations) { |
752 does_deopt = !instr->CheckFlag(HInstruction::kUint32); | 742 does_deopt = !instr->CheckFlag(HInstruction::kUint32); |
753 } else { | 743 } else { |
754 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | 744 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { |
755 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { | 745 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { |
756 does_deopt = true; | 746 does_deopt = true; |
757 break; | 747 break; |
758 } | 748 } |
759 } | 749 } |
(...skipping 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2088 | 2078 |
2089 | 2079 |
2090 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { | 2080 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
2091 Representation r = instr->representation(); | 2081 Representation r = instr->representation(); |
2092 if (r.IsSmi()) { | 2082 if (r.IsSmi()) { |
2093 return DefineAsRegister(new(zone()) LConstantS); | 2083 return DefineAsRegister(new(zone()) LConstantS); |
2094 } else if (r.IsInteger32()) { | 2084 } else if (r.IsInteger32()) { |
2095 return DefineAsRegister(new(zone()) LConstantI); | 2085 return DefineAsRegister(new(zone()) LConstantI); |
2096 } else if (r.IsDouble()) { | 2086 } else if (r.IsDouble()) { |
2097 return DefineAsRegister(new(zone()) LConstantD); | 2087 return DefineAsRegister(new(zone()) LConstantD); |
2098 } else if (r.IsExternal()) { | |
2099 return DefineAsRegister(new(zone()) LConstantE); | |
2100 } else if (r.IsTagged()) { | 2088 } else if (r.IsTagged()) { |
2101 return DefineAsRegister(new(zone()) LConstantT); | 2089 return DefineAsRegister(new(zone()) LConstantT); |
2102 } else { | 2090 } else { |
2103 UNREACHABLE(); | 2091 UNREACHABLE(); |
2104 return NULL; | 2092 return NULL; |
2105 } | 2093 } |
2106 } | 2094 } |
2107 | 2095 |
2108 | 2096 |
2109 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { | 2097 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2317 return MarkAsCall(new(zone()) LStoreKeyedGeneric(obj, key, val), instr); | 2305 return MarkAsCall(new(zone()) LStoreKeyedGeneric(obj, key, val), instr); |
2318 } | 2306 } |
2319 | 2307 |
2320 | 2308 |
2321 LInstruction* LChunkBuilder::DoTransitionElementsKind( | 2309 LInstruction* LChunkBuilder::DoTransitionElementsKind( |
2322 HTransitionElementsKind* instr) { | 2310 HTransitionElementsKind* instr) { |
2323 LOperand* object = UseRegister(instr->object()); | 2311 LOperand* object = UseRegister(instr->object()); |
2324 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { | 2312 if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { |
2325 LOperand* new_map_reg = TempRegister(); | 2313 LOperand* new_map_reg = TempRegister(); |
2326 LTransitionElementsKind* result = | 2314 LTransitionElementsKind* result = |
2327 new(zone()) LTransitionElementsKind(object, new_map_reg); | 2315 new(zone()) LTransitionElementsKind(object, new_map_reg, NULL); |
2328 return result; | 2316 return result; |
| 2317 } else if (FLAG_compiled_transitions) { |
| 2318 LTransitionElementsKind* result = |
| 2319 new(zone()) LTransitionElementsKind(object, NULL, NULL); |
| 2320 return AssignPointerMap(result); |
2329 } else { | 2321 } else { |
| 2322 LOperand* object = UseFixed(instr->object(), r0); |
| 2323 LOperand* fixed_object_reg = FixedTemp(r2); |
| 2324 LOperand* new_map_reg = FixedTemp(r3); |
2330 LTransitionElementsKind* result = | 2325 LTransitionElementsKind* result = |
2331 new(zone()) LTransitionElementsKind(object, NULL); | 2326 new(zone()) LTransitionElementsKind(object, |
2332 return AssignPointerMap(result); | 2327 new_map_reg, |
| 2328 fixed_object_reg); |
| 2329 return MarkAsCall(result, instr); |
2333 } | 2330 } |
2334 } | 2331 } |
2335 | 2332 |
2336 | 2333 |
2337 LInstruction* LChunkBuilder::DoTrapAllocationMemento( | 2334 LInstruction* LChunkBuilder::DoTrapAllocationMemento( |
2338 HTrapAllocationMemento* instr) { | 2335 HTrapAllocationMemento* instr) { |
2339 LOperand* object = UseRegister(instr->object()); | 2336 LOperand* object = UseRegister(instr->object()); |
2340 LOperand* temp = TempRegister(); | 2337 LOperand* temp = TempRegister(); |
2341 LTrapAllocationMemento* result = | 2338 LTrapAllocationMemento* result = |
2342 new(zone()) LTrapAllocationMemento(object, temp); | 2339 new(zone()) LTrapAllocationMemento(object, temp); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2639 | 2636 |
2640 | 2637 |
2641 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2638 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
2642 LOperand* object = UseRegister(instr->object()); | 2639 LOperand* object = UseRegister(instr->object()); |
2643 LOperand* index = UseRegister(instr->index()); | 2640 LOperand* index = UseRegister(instr->index()); |
2644 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2641 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
2645 } | 2642 } |
2646 | 2643 |
2647 | 2644 |
2648 } } // namespace v8::internal | 2645 } } // namespace v8::internal |
OLD | NEW |