| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 void JumpTarget::Reset() { | 85 void JumpTarget::Reset() { |
| 86 reaching_frames_.Clear(); | 86 reaching_frames_.Clear(); |
| 87 merge_labels_.Clear(); | 87 merge_labels_.Clear(); |
| 88 entry_frame_ = NULL; | 88 entry_frame_ = NULL; |
| 89 entry_label_.Unuse(); | 89 entry_label_.Unuse(); |
| 90 is_bound_ = false; | 90 is_bound_ = false; |
| 91 is_linked_ = false; | 91 is_linked_ = false; |
| 92 } | 92 } |
| 93 | 93 |
| 94 | 94 |
| 95 FrameElement* JumpTarget::Combine(FrameElement* left, FrameElement* right) { | |
| 96 // Given a pair of non-null frame element pointers, return one of | |
| 97 // them as an entry frame candidate or null if they are | |
| 98 // incompatible. | |
| 99 | |
| 100 // If either is invalid, the result is. | |
| 101 if (!left->is_valid()) return left; | |
| 102 if (!right->is_valid()) return right; | |
| 103 | |
| 104 // If they have the exact same location, the result is in that | |
| 105 // location, otherwise we reallocate. If either is unsynced, the | |
| 106 // result is. The result static type is the merge of the static | |
| 107 // types. It's safe to set it on one of the frame elements, and | |
| 108 // harmless too (because we are only going to merge the reaching | |
| 109 // frames and will ensure that the types are coherent, and changing | |
| 110 // the static type does not emit code). | |
| 111 | |
| 112 StaticType type = left->static_type().merge(right->static_type()); | |
| 113 if (left->is_memory() && right->is_memory()) { | |
| 114 left->set_static_type(type); | |
| 115 return left; | |
| 116 } | |
| 117 | |
| 118 if (left->is_register() && right->is_register() && | |
| 119 left->reg().is(right->reg())) { | |
| 120 if (!left->is_synced()) { | |
| 121 left->set_static_type(type); | |
| 122 return left; | |
| 123 } else { | |
| 124 right->set_static_type(type); | |
| 125 return right; | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 if (left->is_constant() && | |
| 130 right->is_constant() && | |
| 131 left->handle().is_identical_to(right->handle())) { | |
| 132 if (!left->is_synced()) { | |
| 133 left->set_static_type(type); | |
| 134 return left; | |
| 135 } else { | |
| 136 right->set_static_type(type); | |
| 137 return right; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 if (left->is_copy() && | |
| 142 right->is_copy() && | |
| 143 left->index() == right->index()) { | |
| 144 if (!left->is_synced()) { | |
| 145 left->set_static_type(type); | |
| 146 return left; | |
| 147 } else { | |
| 148 right->set_static_type(type); | |
| 149 return right; | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 // Otherwise they are incompatible and we will reallocate them. | |
| 154 return NULL; | |
| 155 } | |
| 156 | |
| 157 | |
| 158 void JumpTarget::ComputeEntryFrame(int mergable_elements) { | 95 void JumpTarget::ComputeEntryFrame(int mergable_elements) { |
| 159 // Given: a collection of frames reaching by forward CFG edges and | 96 // Given: a collection of frames reaching by forward CFG edges and |
| 160 // the directionality of the block. Compute: an entry frame for the | 97 // the directionality of the block. Compute: an entry frame for the |
| 161 // block. | 98 // block. |
| 162 | 99 |
| 163 // Choose an initial frame. | 100 // Choose an initial frame. |
| 164 VirtualFrame* initial_frame = reaching_frames_[0]; | 101 VirtualFrame* initial_frame = reaching_frames_[0]; |
| 165 | 102 |
| 166 // A list of pointers to frame elements in the entry frame. NULL | 103 // A list of pointers to frame elements in the entry frame. NULL |
| 167 // indicates that the element has not yet been determined. | 104 // indicates that the element has not yet been determined. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 191 // It's safe to change the static type on the initial frame | 128 // It's safe to change the static type on the initial frame |
| 192 // element, see comment in JumpTarget::Combine. | 129 // element, see comment in JumpTarget::Combine. |
| 193 initial_frame->elements_[i].set_static_type(StaticType::unknown()); | 130 initial_frame->elements_[i].set_static_type(StaticType::unknown()); |
| 194 } | 131 } |
| 195 elements.Add(&initial_frame->elements_[i]); | 132 elements.Add(&initial_frame->elements_[i]); |
| 196 } | 133 } |
| 197 | 134 |
| 198 // Compute elements based on the other reaching frames. | 135 // Compute elements based on the other reaching frames. |
| 199 if (reaching_frames_.length() > 1) { | 136 if (reaching_frames_.length() > 1) { |
| 200 for (int i = 0; i < length; i++) { | 137 for (int i = 0; i < length; i++) { |
| 138 FrameElement* element = elements[i]; |
| 201 for (int j = 1; j < reaching_frames_.length(); j++) { | 139 for (int j = 1; j < reaching_frames_.length(); j++) { |
| 202 FrameElement* element = elements[i]; | |
| 203 | |
| 204 // Element computation is monotonic: new information will not | 140 // Element computation is monotonic: new information will not |
| 205 // change our decision about undetermined or invalid elements. | 141 // change our decision about undetermined or invalid elements. |
| 206 if (element == NULL || !element->is_valid()) break; | 142 if (element == NULL || !element->is_valid()) break; |
| 207 | 143 |
| 208 elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]); | 144 element = element->Combine(&reaching_frames_[j]->elements_[i]); |
| 209 } | 145 } |
| 146 elements[i] = element; |
| 210 } | 147 } |
| 211 } | 148 } |
| 212 | 149 |
| 213 // Build the new frame. A freshly allocated frame has memory elements | 150 // Build the new frame. A freshly allocated frame has memory elements |
| 214 // for the parameters and some platform-dependent elements (e.g., | 151 // for the parameters and some platform-dependent elements (e.g., |
| 215 // return address). Replace those first. | 152 // return address). Replace those first. |
| 216 entry_frame_ = new VirtualFrame(cgen_); | 153 entry_frame_ = new VirtualFrame(cgen_); |
| 217 int index = 0; | 154 int index = 0; |
| 218 for (; index < entry_frame_->elements_.length(); index++) { | 155 for (; index < entry_frame_->elements_.length(); index++) { |
| 156 FrameElement* target = elements[index]; |
| 219 // If the element is determined, set it now. Count registers. Mark | 157 // If the element is determined, set it now. Count registers. Mark |
| 220 // elements as copied exactly when they have a copy. Undetermined | 158 // elements as copied exactly when they have a copy. Undetermined |
| 221 // elements are initially recorded as if in memory. | 159 // elements are initially recorded as if in memory. |
| 222 if (elements[index] != NULL) { | 160 if (target != NULL) { |
| 223 entry_frame_->elements_[index] = *elements[index]; | 161 entry_frame_->elements_[index] = *target; |
| 224 entry_frame_->elements_[index].clear_copied(); | 162 entry_frame_->InitializeEntryElement(index, target); |
| 225 if (elements[index]->is_register()) { | |
| 226 entry_frame_->register_locations_[elements[index]->reg().code()] = | |
| 227 index; | |
| 228 } else if (elements[index]->is_copy()) { | |
| 229 entry_frame_->elements_[elements[index]->index()].set_copied(); | |
| 230 } | |
| 231 } | 163 } |
| 232 } | 164 } |
| 233 // Then fill in the rest of the frame with new elements. | 165 // Then fill in the rest of the frame with new elements. |
| 234 for (; index < length; index++) { | 166 for (; index < length; index++) { |
| 235 if (elements[index] == NULL) { | 167 FrameElement* target = elements[index]; |
| 168 if (target == NULL) { |
| 236 entry_frame_->elements_.Add(FrameElement::MemoryElement()); | 169 entry_frame_->elements_.Add(FrameElement::MemoryElement()); |
| 237 } else { | 170 } else { |
| 238 entry_frame_->elements_.Add(*elements[index]); | 171 entry_frame_->elements_.Add(*target); |
| 239 entry_frame_->elements_[index].clear_copied(); | 172 entry_frame_->InitializeEntryElement(index, target); |
| 240 if (elements[index]->is_register()) { | |
| 241 entry_frame_->register_locations_[elements[index]->reg().code()] = | |
| 242 index; | |
| 243 } else if (elements[index]->is_copy()) { | |
| 244 entry_frame_->elements_[elements[index]->index()].set_copied(); | |
| 245 } | |
| 246 } | 173 } |
| 247 } | 174 } |
| 248 | 175 |
| 249 // Allocate any still-undetermined frame elements to registers or | 176 // Allocate any still-undetermined frame elements to registers or |
| 250 // memory, from the top down. | 177 // memory, from the top down. |
| 251 for (int i = length - 1; i >= 0; i--) { | 178 for (int i = length - 1; i >= 0; i--) { |
| 252 if (elements[i] == NULL) { | 179 if (elements[i] == NULL) { |
| 253 // Loop over all the reaching frames to check whether the element | 180 // Loop over all the reaching frames to check whether the element |
| 254 // is synced on all frames, to count the registers it occupies, | 181 // is synced on all frames, to count the registers it occupies, |
| 255 // and to compute a merged static type. | 182 // and to compute a merged static type. |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 temp.CopyTo(this); | 673 temp.CopyTo(this); |
| 747 temp.Reset(); // So the destructor does not deallocate virtual frames. | 674 temp.Reset(); // So the destructor does not deallocate virtual frames. |
| 748 | 675 |
| 749 #ifdef DEBUG | 676 #ifdef DEBUG |
| 750 is_shadowing_ = false; | 677 is_shadowing_ = false; |
| 751 #endif | 678 #endif |
| 752 } | 679 } |
| 753 | 680 |
| 754 | 681 |
| 755 } } // namespace v8::internal | 682 } } // namespace v8::internal |
| OLD | NEW |