| 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 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 // Make sure that the lithium instruction has either no fixed register | 931 // Make sure that the lithium instruction has either no fixed register |
| 932 // constraints in temps or the result OR no uses that are only used at | 932 // constraints in temps or the result OR no uses that are only used at |
| 933 // start. If this invariant doesn't hold, the register allocator can decide | 933 // start. If this invariant doesn't hold, the register allocator can decide |
| 934 // to insert a split of a range immediately before the instruction due to an | 934 // to insert a split of a range immediately before the instruction due to an |
| 935 // already allocated register needing to be used for the instruction's fixed | 935 // already allocated register needing to be used for the instruction's fixed |
| 936 // register constraint. In this case, The register allocator won't see an | 936 // register constraint. In this case, The register allocator won't see an |
| 937 // interference between the split child and the use-at-start (it would if | 937 // interference between the split child and the use-at-start (it would if |
| 938 // the it was just a plain use), so it is free to move the split child into | 938 // the it was just a plain use), so it is free to move the split child into |
| 939 // the same register that is used for the use-at-start. | 939 // the same register that is used for the use-at-start. |
| 940 // See https://code.google.com/p/chromium/issues/detail?id=201590 | 940 // See https://code.google.com/p/chromium/issues/detail?id=201590 |
| 941 if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) { | 941 if (!(instr->ClobbersRegisters() && |
| 942 instr->ClobbersDoubleRegisters(isolate()))) { |
| 942 int fixed = 0; | 943 int fixed = 0; |
| 943 int used_at_start = 0; | 944 int used_at_start = 0; |
| 944 for (UseIterator it(instr); !it.Done(); it.Advance()) { | 945 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
| 945 LUnallocated* operand = LUnallocated::cast(it.Current()); | 946 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 946 if (operand->IsUsedAtStart()) ++used_at_start; | 947 if (operand->IsUsedAtStart()) ++used_at_start; |
| 947 } | 948 } |
| 948 if (instr->Output() != NULL) { | 949 if (instr->Output() != NULL) { |
| 949 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; | 950 if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed; |
| 950 } | 951 } |
| 951 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 952 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 952 LUnallocated* operand = LUnallocated::cast(it.Current()); | 953 LUnallocated* operand = LUnallocated::cast(it.Current()); |
| 953 if (operand->HasFixedPolicy()) ++fixed; | 954 if (operand->HasFixedPolicy()) ++fixed; |
| 954 } | 955 } |
| 955 ASSERT(fixed == 0 || used_at_start == 0); | 956 ASSERT(fixed == 0 || used_at_start == 0); |
| 956 } | 957 } |
| 957 #endif | 958 #endif |
| 958 | 959 |
| 959 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 960 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 960 instr = AssignPointerMap(instr); | 961 instr = AssignPointerMap(instr); |
| 961 } | 962 } |
| 962 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 963 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 963 instr = AssignEnvironment(instr); | 964 instr = AssignEnvironment(instr); |
| 964 } | 965 } |
| 965 if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() && | 966 if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && instr->IsGoto() && |
| 966 LGoto::cast(instr)->jumps_to_join()) { | 967 LGoto::cast(instr)->jumps_to_join()) { |
| 967 // TODO(olivf) Since phis of spilled values are joined as registers | 968 // TODO(olivf) Since phis of spilled values are joined as registers |
| 968 // (not in the stack slot), we need to allow the goto gaps to keep one | 969 // (not in the stack slot), we need to allow the goto gaps to keep one |
| 969 // x87 register alive. To ensure all other values are still spilled, we | 970 // x87 register alive. To ensure all other values are still spilled, we |
| 970 // insert a fpu register barrier right before. | 971 // insert a fpu register barrier right before. |
| 971 LClobberDoubles* clobber = new(zone()) LClobberDoubles(); | 972 LClobberDoubles* clobber = new(zone()) LClobberDoubles(isolate()); |
| 972 clobber->set_hydrogen_value(current); | 973 clobber->set_hydrogen_value(current); |
| 973 chunk_->AddInstruction(clobber, current_block_); | 974 chunk_->AddInstruction(clobber, current_block_); |
| 974 } | 975 } |
| 975 chunk_->AddInstruction(instr, current_block_); | 976 chunk_->AddInstruction(instr, current_block_); |
| 976 | 977 |
| 977 if (instr->IsCall()) { | 978 if (instr->IsCall()) { |
| 978 HValue* hydrogen_value_for_lazy_bailout = current; | 979 HValue* hydrogen_value_for_lazy_bailout = current; |
| 979 LInstruction* instruction_needing_environment = NULL; | 980 LInstruction* instruction_needing_environment = NULL; |
| 980 if (current->HasObservableSideEffects()) { | 981 if (current->HasObservableSideEffects()) { |
| 981 HSimulate* sim = HSimulate::cast(current->next()); | 982 HSimulate* sim = HSimulate::cast(current->next()); |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1934 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1935 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
| 1935 } else { | 1936 } else { |
| 1936 ASSERT(to.IsInteger32()); | 1937 ASSERT(to.IsInteger32()); |
| 1937 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1938 if (val->type().IsSmi() || val->representation().IsSmi()) { |
| 1938 LOperand* value = UseRegister(val); | 1939 LOperand* value = UseRegister(val); |
| 1939 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); | 1940 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
| 1940 } else { | 1941 } else { |
| 1941 LOperand* value = UseRegister(val); | 1942 LOperand* value = UseRegister(val); |
| 1942 bool truncating = instr->CanTruncateToInt32(); | 1943 bool truncating = instr->CanTruncateToInt32(); |
| 1943 LOperand* xmm_temp = | 1944 LOperand* xmm_temp = |
| 1944 (CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating) | 1945 (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating) |
| 1945 ? FixedTemp(xmm1) : NULL; | 1946 ? FixedTemp(xmm1) : NULL; |
| 1946 LInstruction* result = | 1947 LInstruction* result = |
| 1947 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); | 1948 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); |
| 1948 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1949 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1949 return result; | 1950 return result; |
| 1950 } | 1951 } |
| 1951 } | 1952 } |
| 1952 } else if (from.IsDouble()) { | 1953 } else if (from.IsDouble()) { |
| 1953 if (to.IsTagged()) { | 1954 if (to.IsTagged()) { |
| 1954 info()->MarkAsDeferredCalling(); | 1955 info()->MarkAsDeferredCalling(); |
| 1955 LOperand* value = UseRegisterAtStart(val); | 1956 LOperand* value = UseRegisterAtStart(val); |
| 1956 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; | 1957 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; |
| 1957 LUnallocated* result_temp = TempRegister(); | 1958 LUnallocated* result_temp = TempRegister(); |
| 1958 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); | 1959 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); |
| 1959 return AssignPointerMap(Define(result, result_temp)); | 1960 return AssignPointerMap(Define(result, result_temp)); |
| 1960 } else if (to.IsSmi()) { | 1961 } else if (to.IsSmi()) { |
| 1961 LOperand* value = UseRegister(val); | 1962 LOperand* value = UseRegister(val); |
| 1962 return AssignEnvironment( | 1963 return AssignEnvironment( |
| 1963 DefineAsRegister(new(zone()) LDoubleToSmi(value))); | 1964 DefineAsRegister(new(zone()) LDoubleToSmi(value))); |
| 1964 } else { | 1965 } else { |
| 1965 ASSERT(to.IsInteger32()); | 1966 ASSERT(to.IsInteger32()); |
| 1966 bool truncating = instr->CanTruncateToInt32(); | 1967 bool truncating = instr->CanTruncateToInt32(); |
| 1967 bool needs_temp = CpuFeatures::IsSafeForSnapshot(SSE2) && !truncating; | 1968 bool needs_temp = |
| 1969 CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating; |
| 1968 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); | 1970 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); |
| 1969 LOperand* temp = needs_temp ? TempRegister() : NULL; | 1971 LOperand* temp = needs_temp ? TempRegister() : NULL; |
| 1970 LInstruction* result = | 1972 LInstruction* result = |
| 1971 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); | 1973 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); |
| 1972 if (!truncating) result = AssignEnvironment(result); | 1974 if (!truncating) result = AssignEnvironment(result); |
| 1973 return result; | 1975 return result; |
| 1974 } | 1976 } |
| 1975 } else if (from.IsInteger32()) { | 1977 } else if (from.IsInteger32()) { |
| 1976 info()->MarkAsDeferredCalling(); | 1978 info()->MarkAsDeferredCalling(); |
| 1977 if (to.IsTagged()) { | 1979 if (to.IsTagged()) { |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2275 elements_kind == EXTERNAL_INT8_ELEMENTS || | 2277 elements_kind == EXTERNAL_INT8_ELEMENTS || |
| 2276 elements_kind == EXTERNAL_UINT8_ELEMENTS || | 2278 elements_kind == EXTERNAL_UINT8_ELEMENTS || |
| 2277 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || | 2279 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || |
| 2278 elements_kind == UINT8_ELEMENTS || | 2280 elements_kind == UINT8_ELEMENTS || |
| 2279 elements_kind == INT8_ELEMENTS || | 2281 elements_kind == INT8_ELEMENTS || |
| 2280 elements_kind == UINT8_CLAMPED_ELEMENTS; | 2282 elements_kind == UINT8_CLAMPED_ELEMENTS; |
| 2281 if (val_is_fixed_register) { | 2283 if (val_is_fixed_register) { |
| 2282 return UseFixed(instr->value(), eax); | 2284 return UseFixed(instr->value(), eax); |
| 2283 } | 2285 } |
| 2284 | 2286 |
| 2285 if (!CpuFeatures::IsSafeForSnapshot(SSE2) && | 2287 if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && |
| 2286 IsDoubleOrFloatElementsKind(elements_kind)) { | 2288 IsDoubleOrFloatElementsKind(elements_kind)) { |
| 2287 return UseRegisterAtStart(instr->value()); | 2289 return UseRegisterAtStart(instr->value()); |
| 2288 } | 2290 } |
| 2289 | 2291 |
| 2290 return UseRegister(instr->value()); | 2292 return UseRegister(instr->value()); |
| 2291 } | 2293 } |
| 2292 | 2294 |
| 2293 | 2295 |
| 2294 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2296 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2295 if (!instr->is_typed_elements()) { | 2297 if (!instr->is_typed_elements()) { |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2721 LOperand* index = UseTempRegister(instr->index()); | 2723 LOperand* index = UseTempRegister(instr->index()); |
| 2722 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2724 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
| 2723 LInstruction* result = DefineSameAsFirst(load); | 2725 LInstruction* result = DefineSameAsFirst(load); |
| 2724 return AssignPointerMap(result); | 2726 return AssignPointerMap(result); |
| 2725 } | 2727 } |
| 2726 | 2728 |
| 2727 | 2729 |
| 2728 } } // namespace v8::internal | 2730 } } // namespace v8::internal |
| 2729 | 2731 |
| 2730 #endif // V8_TARGET_ARCH_IA32 | 2732 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |