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 |