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