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 |