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 intptr_t ParallelMoveResolver::AllocateScratchRegister(Location::Kind kind, |
| 969 intptr_t blocked, |
| 970 intptr_t register_count, |
| 971 bool* spilled) { |
| 972 intptr_t scratch = -1; |
| 973 for (intptr_t reg = 0; reg < register_count; reg++) { |
| 974 if ((blocked != reg) && |
| 975 IsScratchLocation(Location::MachineRegisterLocation(kind, reg))) { |
| 976 scratch = reg; |
| 977 break; |
| 978 } |
| 979 } |
| 980 |
| 981 if (scratch == -1) { |
| 982 *spilled = true; |
| 983 for (intptr_t reg = 0; reg < register_count; reg++) { |
| 984 if (blocked != reg) { |
| 985 scratch = reg; |
| 986 } |
| 987 } |
| 988 } else { |
| 989 *spilled = false; |
| 990 } |
| 991 |
| 992 return scratch; |
| 993 } |
| 994 |
| 995 |
| 996 ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope( |
| 997 ParallelMoveResolver* resolver, FpuRegister blocked) |
| 998 : resolver_(resolver), |
| 999 reg_(kNoFpuRegister), |
| 1000 spilled_(false) { |
| 1001 reg_ = static_cast<FpuRegister>( |
| 1002 resolver_->AllocateScratchRegister(Location::kFpuRegister, |
| 1003 blocked, |
| 1004 kNumberOfFpuRegisters, |
| 1005 &spilled_)); |
| 1006 |
| 1007 if (spilled_) { |
| 1008 resolver->SpillFpuScratch(reg_); |
| 1009 } |
| 1010 } |
| 1011 |
| 1012 |
| 1013 ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() { |
| 1014 if (spilled_) { |
| 1015 resolver_->RestoreFpuScratch(reg_); |
| 1016 } |
| 1017 } |
| 1018 |
| 1019 |
| 1020 ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope( |
| 1021 ParallelMoveResolver* resolver, Register blocked) |
| 1022 : resolver_(resolver), |
| 1023 reg_(kNoRegister), |
| 1024 spilled_(false) { |
| 1025 reg_ = static_cast<Register>( |
| 1026 resolver_->AllocateScratchRegister(Location::kRegister, |
| 1027 blocked, |
| 1028 kNumberOfCpuRegisters, |
| 1029 &spilled_)); |
| 1030 |
| 1031 if (spilled_) { |
| 1032 resolver->SpillScratch(reg_); |
| 1033 } |
| 1034 } |
| 1035 |
| 1036 |
| 1037 ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() { |
| 1038 if (spilled_) { |
| 1039 resolver_->RestoreScratch(reg_); |
| 1040 } |
| 1041 } |
| 1042 |
| 1043 |
947 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { | 1044 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { |
948 if (RawObject::IsExternalTypedDataClassId(cid)) { | 1045 if (RawObject::IsExternalTypedDataClassId(cid)) { |
949 return ExternalTypedData::ElementSizeInBytes(cid); | 1046 return ExternalTypedData::ElementSizeInBytes(cid); |
950 } else if (RawObject::IsTypedDataClassId(cid)) { | 1047 } else if (RawObject::IsTypedDataClassId(cid)) { |
951 return TypedData::ElementSizeInBytes(cid); | 1048 return TypedData::ElementSizeInBytes(cid); |
952 } | 1049 } |
953 switch (cid) { | 1050 switch (cid) { |
954 case kArrayCid: | 1051 case kArrayCid: |
955 case kImmutableArrayCid: | 1052 case kImmutableArrayCid: |
956 return Array::kBytesPerElement; | 1053 return Array::kBytesPerElement; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 if (i != largest_ix) { | 1134 if (i != largest_ix) { |
1038 // Swap. | 1135 // Swap. |
1039 CidTarget temp = (*sorted)[i]; | 1136 CidTarget temp = (*sorted)[i]; |
1040 (*sorted)[i] = (*sorted)[largest_ix]; | 1137 (*sorted)[i] = (*sorted)[largest_ix]; |
1041 (*sorted)[largest_ix] = temp; | 1138 (*sorted)[largest_ix] = temp; |
1042 } | 1139 } |
1043 } | 1140 } |
1044 } | 1141 } |
1045 | 1142 |
1046 } // namespace dart | 1143 } // namespace dart |
OLD | NEW |