OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "lithium-allocator-inl.h" | 9 #include "lithium-allocator-inl.h" |
10 #include "ia32/lithium-ia32.h" | 10 #include "ia32/lithium-ia32.h" |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 // Make sure that the lithium instruction has either no fixed register | 908 // Make sure that the lithium instruction has either no fixed register |
909 // constraints in temps or the result OR no uses that are only used at | 909 // constraints in temps or the result OR no uses that are only used at |
910 // start. If this invariant doesn't hold, the register allocator can decide | 910 // start. If this invariant doesn't hold, the register allocator can decide |
911 // to insert a split of a range immediately before the instruction due to an | 911 // to insert a split of a range immediately before the instruction due to an |
912 // already allocated register needing to be used for the instruction's fixed | 912 // already allocated register needing to be used for the instruction's fixed |
913 // register constraint. In this case, The register allocator won't see an | 913 // register constraint. In this case, The register allocator won't see an |
914 // interference between the split child and the use-at-start (it would if | 914 // interference between the split child and the use-at-start (it would if |
915 // the it was just a plain use), so it is free to move the split child into | 915 // the it was just a plain use), so it is free to move the split child into |
916 // the same register that is used for the use-at-start. | 916 // the same register that is used for the use-at-start. |
917 // See https://code.google.com/p/chromium/issues/detail?id=201590 | 917 // See https://code.google.com/p/chromium/issues/detail?id=201590 |
918 if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) { | 918 if (!(instr->ClobbersRegisters() && |
| 919 instr->ClobbersDoubleRegisters(isolate()))) { |
919 int fixed = 0; | 920 int fixed = 0; |
920 int used_at_start = 0; | 921 int used_at_start = 0; |
921 for (UseIterator it(instr); !it.Done(); it.Advance()) { | 922 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
922 LUnallocated* operand = LUnallocated::cast(it.Current()); | 923 LUnallocated* operand = LUnallocated::cast(it.Current()); |
923 if (operand->IsUsedAtStart()) ++used_at_start; | 924 if (operand->IsUsedAtStart()) ++used_at_start; |
924 } | 925 } |
925 if (instr->Output() != NULL) { | 926 if (instr->Output() != NULL) { |
926 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; | 927 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
927 } | 928 } |
928 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 929 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
929 LUnallocated* operand = LUnallocated::cast(it.Current()); | 930 LUnallocated* operand = LUnallocated::cast(it.Current()); |
930 if (operand->HasFixedPolicy()) ++fixed; | 931 if (operand->HasFixedPolicy()) ++fixed; |
931 } | 932 } |
932 ASSERT(fixed == 0 || used_at_start == 0); | 933 ASSERT(fixed == 0 || used_at_start == 0); |
933 } | 934 } |
934 #endif | 935 #endif |
935 | 936 |
936 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 937 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
937 instr = AssignPointerMap(instr); | 938 instr = AssignPointerMap(instr); |
938 } | 939 } |
939 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 940 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
940 instr = AssignEnvironment(instr); | 941 instr = AssignEnvironment(instr); |
941 } | 942 } |
942 if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() && | 943 if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && instr->IsGoto() && |
943 LGoto::cast(instr)->jumps_to_join()) { | 944 LGoto::cast(instr)->jumps_to_join()) { |
944 // TODO(olivf) Since phis of spilled values are joined as registers | 945 // TODO(olivf) Since phis of spilled values are joined as registers |
945 // (not in the stack slot), we need to allow the goto gaps to keep one | 946 // (not in the stack slot), we need to allow the goto gaps to keep one |
946 // x87 register alive. To ensure all other values are still spilled, we | 947 // x87 register alive. To ensure all other values are still spilled, we |
947 // insert a fpu register barrier right before. | 948 // insert a fpu register barrier right before. |
948 LClobberDoubles* clobber = new(zone()) LClobberDoubles(); | 949 LClobberDoubles* clobber = new(zone()) LClobberDoubles(isolate()); |
949 clobber->set_hydrogen_value(current); | 950 clobber->set_hydrogen_value(current); |
950 chunk_->AddInstruction(clobber, current_block_); | 951 chunk_->AddInstruction(clobber, current_block_); |
951 } | 952 } |
952 chunk_->AddInstruction(instr, current_block_); | 953 chunk_->AddInstruction(instr, current_block_); |
953 | 954 |
954 if (instr->IsCall()) { | 955 if (instr->IsCall()) { |
955 HValue* hydrogen_value_for_lazy_bailout = current; | 956 HValue* hydrogen_value_for_lazy_bailout = current; |
956 LInstruction* instruction_needing_environment = NULL; | 957 LInstruction* instruction_needing_environment = NULL; |
957 if (current->HasObservableSideEffects()) { | 958 if (current->HasObservableSideEffects()) { |
958 HSimulate* sim = HSimulate::cast(current->next()); | 959 HSimulate* sim = HSimulate::cast(current->next()); |
(...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1911 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1912 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
1912 } else { | 1913 } else { |
1913 ASSERT(to.IsInteger32()); | 1914 ASSERT(to.IsInteger32()); |
1914 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1915 if (val->type().IsSmi() || val->representation().IsSmi()) { |
1915 LOperand* value = UseRegister(val); | 1916 LOperand* value = UseRegister(val); |
1916 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); | 1917 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
1917 } else { | 1918 } else { |
1918 LOperand* value = UseRegister(val); | 1919 LOperand* value = UseRegister(val); |
1919 bool truncating = instr->CanTruncateToInt32(); | 1920 bool truncating = instr->CanTruncateToInt32(); |
1920 LOperand* xmm_temp = | 1921 LOperand* xmm_temp = |
1921 (CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating) | 1922 (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating) |
1922 ? FixedTemp(xmm1) : NULL; | 1923 ? FixedTemp(xmm1) : NULL; |
1923 LInstruction* result = | 1924 LInstruction* result = |
1924 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); | 1925 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); |
1925 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1926 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
1926 return result; | 1927 return result; |
1927 } | 1928 } |
1928 } | 1929 } |
1929 } else if (from.IsDouble()) { | 1930 } else if (from.IsDouble()) { |
1930 if (to.IsTagged()) { | 1931 if (to.IsTagged()) { |
1931 info()->MarkAsDeferredCalling(); | 1932 info()->MarkAsDeferredCalling(); |
1932 LOperand* value = UseRegisterAtStart(val); | 1933 LOperand* value = UseRegisterAtStart(val); |
1933 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; | 1934 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; |
1934 LUnallocated* result_temp = TempRegister(); | 1935 LUnallocated* result_temp = TempRegister(); |
1935 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); | 1936 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); |
1936 return AssignPointerMap(Define(result, result_temp)); | 1937 return AssignPointerMap(Define(result, result_temp)); |
1937 } else if (to.IsSmi()) { | 1938 } else if (to.IsSmi()) { |
1938 LOperand* value = UseRegister(val); | 1939 LOperand* value = UseRegister(val); |
1939 return AssignEnvironment( | 1940 return AssignEnvironment( |
1940 DefineAsRegister(new(zone()) LDoubleToSmi(value))); | 1941 DefineAsRegister(new(zone()) LDoubleToSmi(value))); |
1941 } else { | 1942 } else { |
1942 ASSERT(to.IsInteger32()); | 1943 ASSERT(to.IsInteger32()); |
1943 bool truncating = instr->CanTruncateToInt32(); | 1944 bool truncating = instr->CanTruncateToInt32(); |
1944 bool needs_temp = CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating; | 1945 bool needs_temp = |
| 1946 CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating; |
1945 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); | 1947 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); |
1946 LOperand* temp = needs_temp ? TempRegister() : NULL; | 1948 LOperand* temp = needs_temp ? TempRegister() : NULL; |
1947 LInstruction* result = | 1949 LInstruction* result = |
1948 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); | 1950 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); |
1949 if (!truncating) result = AssignEnvironment(result); | 1951 if (!truncating) result = AssignEnvironment(result); |
1950 return result; | 1952 return result; |
1951 } | 1953 } |
1952 } else if (from.IsInteger32()) { | 1954 } else if (from.IsInteger32()) { |
1953 info()->MarkAsDeferredCalling(); | 1955 info()->MarkAsDeferredCalling(); |
1954 if (to.IsTagged()) { | 1956 if (to.IsTagged()) { |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 elements_kind == EXTERNAL_INT8_ELEMENTS || | 2254 elements_kind == EXTERNAL_INT8_ELEMENTS || |
2253 elements_kind == EXTERNAL_UINT8_ELEMENTS || | 2255 elements_kind == EXTERNAL_UINT8_ELEMENTS || |
2254 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || | 2256 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || |
2255 elements_kind == UINT8_ELEMENTS || | 2257 elements_kind == UINT8_ELEMENTS || |
2256 elements_kind == INT8_ELEMENTS || | 2258 elements_kind == INT8_ELEMENTS || |
2257 elements_kind == UINT8_CLAMPED_ELEMENTS; | 2259 elements_kind == UINT8_CLAMPED_ELEMENTS; |
2258 if (val_is_fixed_register) { | 2260 if (val_is_fixed_register) { |
2259 return UseFixed(instr->value(), eax); | 2261 return UseFixed(instr->value(), eax); |
2260 } | 2262 } |
2261 | 2263 |
2262 if (!CpuFeatures::IsSafeForSnapshot(SSE2) && | 2264 if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && |
2263 IsDoubleOrFloatElementsKind(elements_kind)) { | 2265 IsDoubleOrFloatElementsKind(elements_kind)) { |
2264 return UseRegisterAtStart(instr->value()); | 2266 return UseRegisterAtStart(instr->value()); |
2265 } | 2267 } |
2266 | 2268 |
2267 return UseRegister(instr->value()); | 2269 return UseRegister(instr->value()); |
2268 } | 2270 } |
2269 | 2271 |
2270 | 2272 |
2271 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2273 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
2272 if (!instr->is_typed_elements()) { | 2274 if (!instr->is_typed_elements()) { |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2698 LOperand* index = UseTempRegister(instr->index()); | 2700 LOperand* index = UseTempRegister(instr->index()); |
2699 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2701 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
2700 LInstruction* result = DefineSameAsFirst(load); | 2702 LInstruction* result = DefineSameAsFirst(load); |
2701 return AssignPointerMap(result); | 2703 return AssignPointerMap(result); |
2702 } | 2704 } |
2703 | 2705 |
2704 | 2706 |
2705 } } // namespace v8::internal | 2707 } } // namespace v8::internal |
2706 | 2708 |
2707 #endif // V8_TARGET_ARCH_IA32 | 2709 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |