Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX. |
| 6 | 6 |
| 7 #include "vm/flow_graph_compiler.h" | 7 #include "vm/flow_graph_compiler.h" |
| 8 | 8 |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 intptr_t slot_ix = 0; | 72 intptr_t slot_ix = 0; |
| 73 Environment* current = deoptimization_env_; | 73 Environment* current = deoptimization_env_; |
| 74 | 74 |
| 75 // For the innermost environment, call the virtual return builder. | 75 // For the innermost environment, call the virtual return builder. |
| 76 BuildReturnAddress(builder, current->function(), slot_ix++); | 76 BuildReturnAddress(builder, current->function(), slot_ix++); |
| 77 | 77 |
| 78 // For the innermost environment, set outgoing arguments and the locals. | 78 // For the innermost environment, set outgoing arguments and the locals. |
| 79 for (intptr_t i = current->Length() - 1; | 79 for (intptr_t i = current->Length() - 1; |
| 80 i >= current->fixed_parameter_count(); | 80 i >= current->fixed_parameter_count(); |
| 81 i--) { | 81 i--) { |
| 82 builder->AddCopy(current->LocationAt(i), slot_ix++); | 82 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); |
| 83 } | 83 } |
| 84 | 84 |
| 85 // PC marker and caller FP. | 85 // PC marker and caller FP. |
| 86 builder->AddPcMarker(current->function(), slot_ix++); | 86 builder->AddPcMarker(current->function(), slot_ix++); |
| 87 builder->AddCallerFp(slot_ix++); | 87 builder->AddCallerFp(slot_ix++); |
| 88 | 88 |
| 89 Environment* previous = current; | 89 Environment* previous = current; |
| 90 current = current->outer(); | 90 current = current->outer(); |
| 91 while (current != NULL) { | 91 while (current != NULL) { |
| 92 // For any outer environment the deopt id is that of the call instruction | 92 // For any outer environment the deopt id is that of the call instruction |
| 93 // which is recorded in the outer environment. | 93 // which is recorded in the outer environment. |
| 94 builder->AddReturnAddressAfter(current->function(), | 94 builder->AddReturnAddressAfter(current->function(), |
| 95 current->deopt_id(), | 95 current->deopt_id(), |
| 96 slot_ix++); | 96 slot_ix++); |
| 97 | 97 |
| 98 // The values of outgoing arguments can be changed from the inlined call so | 98 // The values of outgoing arguments can be changed from the inlined call so |
| 99 // we must read them from the previous environment. | 99 // we must read them from the previous environment. |
| 100 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { | 100 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { |
| 101 builder->AddCopy(previous->LocationAt(i), slot_ix++); | 101 builder->AddCopy(previous->ValueAt(i), |
| 102 previous->LocationAt(i), | |
| 103 slot_ix++); | |
| 102 } | 104 } |
| 103 | 105 |
| 104 // Set the locals, note that outgoing arguments are not in the environment. | 106 // Set the locals, note that outgoing arguments are not in the environment. |
| 105 for (intptr_t i = current->Length() - 1; | 107 for (intptr_t i = current->Length() - 1; |
| 106 i >= current->fixed_parameter_count(); | 108 i >= current->fixed_parameter_count(); |
| 107 i--) { | 109 i--) { |
| 108 builder->AddCopy(current->LocationAt(i), slot_ix++); | 110 builder->AddCopy(current->ValueAt(i), |
| 111 current->LocationAt(i), | |
| 112 slot_ix++); | |
| 109 } | 113 } |
| 110 | 114 |
| 111 // PC marker and caller FP. | 115 // PC marker and caller FP. |
| 112 builder->AddPcMarker(current->function(), slot_ix++); | 116 builder->AddPcMarker(current->function(), slot_ix++); |
| 113 builder->AddCallerFp(slot_ix++); | 117 builder->AddCallerFp(slot_ix++); |
| 114 | 118 |
| 115 // Iterate on the outer environment. | 119 // Iterate on the outer environment. |
| 116 previous = current; | 120 previous = current; |
| 117 current = current->outer(); | 121 current = current->outer(); |
| 118 } | 122 } |
| 119 // The previous pointer is now the outermost environment. | 123 // The previous pointer is now the outermost environment. |
| 120 ASSERT(previous != NULL); | 124 ASSERT(previous != NULL); |
| 121 | 125 |
| 122 // For the outermost environment, set caller PC. | 126 // For the outermost environment, set caller PC. |
| 123 builder->AddCallerPc(slot_ix++); | 127 builder->AddCallerPc(slot_ix++); |
| 124 | 128 |
| 125 // For the outermost environment, set the incoming arguments. | 129 // For the outermost environment, set the incoming arguments. |
| 126 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { | 130 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { |
| 127 builder->AddCopy(previous->LocationAt(i), slot_ix++); | 131 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); |
| 128 } | 132 } |
| 129 | 133 |
| 130 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo()); | 134 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo()); |
| 131 return deopt_info.raw(); | 135 return deopt_info.raw(); |
| 132 } | 136 } |
| 133 | 137 |
| 134 | 138 |
| 135 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, | 139 FlowGraphCompiler::FlowGraphCompiler(Assembler* assembler, |
| 136 const FlowGraph& flow_graph, | 140 const FlowGraph& flow_graph, |
| 137 bool is_optimizing) | 141 bool is_optimizing) |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 RegisterSet* regs = locs->live_registers(); | 413 RegisterSet* regs = locs->live_registers(); |
| 410 if (regs->fpu_regs_count() > 0) { | 414 if (regs->fpu_regs_count() > 0) { |
| 411 // Denote FPU registers with 0 bits in the stackmap. Based on the | 415 // Denote FPU registers with 0 bits in the stackmap. Based on the |
| 412 // assumption that there are normally few live FPU registers, this | 416 // assumption that there are normally few live FPU registers, this |
| 413 // encoding is simpler and roughly as compact as storing a separate | 417 // encoding is simpler and roughly as compact as storing a separate |
| 414 // count of FPU registers. | 418 // count of FPU registers. |
| 415 // | 419 // |
| 416 // FPU registers have the highest register number at the highest | 420 // FPU registers have the highest register number at the highest |
| 417 // address (i.e., first in the stackmap). | 421 // address (i.e., first in the stackmap). |
| 418 const intptr_t kFpuRegisterSpillFactor = | 422 const intptr_t kFpuRegisterSpillFactor = |
| 419 FlowGraphAllocator::kFpuRegisterSpillFactor; | 423 kFpuRegisterSize / kWordSize; |
| 420 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) { | 424 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) { |
| 421 FpuRegister reg = static_cast<FpuRegister>(i); | 425 FpuRegister reg = static_cast<FpuRegister>(i); |
| 422 if (regs->ContainsFpuRegister(reg)) { | 426 if (regs->ContainsFpuRegister(reg)) { |
| 423 for (intptr_t j = 0; j < kFpuRegisterSpillFactor; ++j) { | 427 for (intptr_t j = 0; j < kFpuRegisterSpillFactor; ++j) { |
| 424 bitmap->Set(bitmap->Length(), false); | 428 bitmap->Set(bitmap->Length(), false); |
| 425 } | 429 } |
| 426 } | 430 } |
| 427 } | 431 } |
| 428 } | 432 } |
| 429 // General purpose registers have the lowest register number at the | 433 // General purpose registers have the lowest register number at the |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 937 EmitSwap(index); | 941 EmitSwap(index); |
| 938 return; | 942 return; |
| 939 } | 943 } |
| 940 } | 944 } |
| 941 | 945 |
| 942 // This move is not blocked. | 946 // This move is not blocked. |
| 943 EmitMove(index); | 947 EmitMove(index); |
| 944 } | 948 } |
| 945 | 949 |
| 946 | 950 |
| 951 bool ParallelMoveResolver::IsScratchLocation(Location loc) { | |
| 952 for (int i = 0; i < moves_.length(); ++i) { | |
| 953 if (moves_[i]->Blocks(loc)) { | |
| 954 return false; | |
| 955 } | |
| 956 } | |
| 957 | |
| 958 for (int i = 0; i < moves_.length(); ++i) { | |
| 959 if (moves_[i]->dest().Equals(loc)) { | |
| 960 return true; | |
| 961 } | |
| 962 } | |
| 963 | |
| 964 return false; | |
| 965 } | |
| 966 | |
| 967 | |
| 968 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope( | |
|
Florian Schneider
2013/04/09 09:44:27
Can you implement ScratchFpuRegisterScope in using
| |
| 969 ParallelMoveResolver* resolver) | |
| 970 : resolver_(resolver), | |
| 971 reg_(kNoXmmRegister), | |
| 972 spilled_(false) { | |
| 973 ASSERT(XMM0 == 0); | |
| 974 for (intptr_t reg = 1; reg < kNumberOfFpuRegisters; reg++) { | |
| 975 Location scratch = Location::FpuRegisterLocation( | |
| 976 static_cast<FpuRegister>(reg)); | |
| 977 if (resolver->IsScratchLocation(scratch)) { | |
| 978 reg_ = static_cast<FpuRegister>(reg); | |
| 979 break; | |
| 980 } | |
| 981 } | |
| 982 | |
| 983 if (reg_ == kNoXmmRegister) { | |
| 984 spilled_ = true; | |
| 985 reg_ = XMM1; | |
| 986 resolver->SpillFpuScratch(reg_); | |
| 987 } | |
| 988 } | |
| 989 | |
| 990 | |
| 991 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() { | |
| 992 if (spilled_) { | |
| 993 resolver_->RestoreFpuScratch(reg_); | |
| 994 } | |
| 995 } | |
| 996 | |
| 997 | |
| 998 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope( | |
| 999 ParallelMoveResolver* resolver, Register blocked) | |
| 1000 : resolver_(resolver), | |
| 1001 reg_(kNoRegister), | |
| 1002 spilled_(false) { | |
| 1003 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { | |
| 1004 if (blocked == reg) { | |
| 1005 continue; | |
| 1006 } | |
| 1007 | |
| 1008 Location scratch = Location::RegisterLocation( | |
| 1009 static_cast<Register>(reg)); | |
| 1010 if (resolver->IsScratchLocation(scratch)) { | |
| 1011 reg_ = static_cast<Register>(reg); | |
| 1012 break; | |
| 1013 } | |
| 1014 } | |
| 1015 | |
| 1016 if (reg_ == kNoRegister) { | |
| 1017 spilled_ = true; | |
| 1018 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { | |
| 1019 if (blocked != reg) { | |
| 1020 reg_ = static_cast<Register>(reg); | |
| 1021 break; | |
| 1022 } | |
| 1023 } | |
| 1024 resolver->SpillScratch(reg_); | |
| 1025 } | |
| 1026 } | |
| 1027 | |
| 1028 | |
| 1029 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() { | |
| 1030 if (spilled_) { | |
| 1031 resolver_->RestoreScratch(reg_); | |
| 1032 } | |
| 1033 } | |
| 1034 | |
| 1035 | |
| 947 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { | 1036 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { |
| 948 if (RawObject::IsExternalTypedDataClassId(cid)) { | 1037 if (RawObject::IsExternalTypedDataClassId(cid)) { |
| 949 return ExternalTypedData::ElementSizeInBytes(cid); | 1038 return ExternalTypedData::ElementSizeInBytes(cid); |
| 950 } else if (RawObject::IsTypedDataClassId(cid)) { | 1039 } else if (RawObject::IsTypedDataClassId(cid)) { |
| 951 return TypedData::ElementSizeInBytes(cid); | 1040 return TypedData::ElementSizeInBytes(cid); |
| 952 } | 1041 } |
| 953 switch (cid) { | 1042 switch (cid) { |
| 954 case kArrayCid: | 1043 case kArrayCid: |
| 955 case kImmutableArrayCid: | 1044 case kImmutableArrayCid: |
| 956 return Array::kBytesPerElement; | 1045 return Array::kBytesPerElement; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1037 if (i != largest_ix) { | 1126 if (i != largest_ix) { |
| 1038 // Swap. | 1127 // Swap. |
| 1039 CidTarget temp = (*sorted)[i]; | 1128 CidTarget temp = (*sorted)[i]; |
| 1040 (*sorted)[i] = (*sorted)[largest_ix]; | 1129 (*sorted)[i] = (*sorted)[largest_ix]; |
| 1041 (*sorted)[largest_ix] = temp; | 1130 (*sorted)[largest_ix] = temp; |
| 1042 } | 1131 } |
| 1043 } | 1132 } |
| 1044 } | 1133 } |
| 1045 | 1134 |
| 1046 } // namespace dart | 1135 } // namespace dart |
| OLD | NEW |