Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: src/jump-target.cc

Issue 40169: Change the way we handle backward jumps in the code generator. Keep... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/jump-target-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 ASSERT(cgen != NULL); 64 ASSERT(cgen != NULL);
65 ASSERT(cgen_ == NULL); 65 ASSERT(cgen_ == NULL);
66 cgen_ = cgen; 66 cgen_ = cgen;
67 masm_ = cgen->masm(); 67 masm_ = cgen->masm();
68 direction_ = direction; 68 direction_ = direction;
69 } 69 }
70 70
71 71
72 void JumpTarget::Unuse() { 72 void JumpTarget::Unuse() {
73 ASSERT(!is_linked()); 73 ASSERT(!is_linked());
74 #ifdef DEBUG
75 for (int i = 0; i < reaching_frames_.length(); i++) { 74 for (int i = 0; i < reaching_frames_.length(); i++) {
76 ASSERT(reaching_frames_[i] == NULL); 75 delete reaching_frames_[i];
Kasper Lund 2009/03/12 14:45:00 Do you want to NULL them out too in case the JumpT
Kevin Millikin (Chromium) 2009/03/12 14:53:51 Maybe it's safer (in the face of changes). Right
77 } 76 }
78 #endif
79 delete entry_frame_; 77 delete entry_frame_;
80
81 Reset(); 78 Reset();
82 } 79 }
83 80
84 81
85 void JumpTarget::Reset() { 82 void JumpTarget::Reset() {
86 reaching_frames_.Clear(); 83 reaching_frames_.Clear();
87 merge_labels_.Clear(); 84 merge_labels_.Clear();
88 entry_frame_ = NULL; 85 entry_frame_ = NULL;
89 entry_label_.Unuse(); 86 entry_label_.Unuse();
90 is_bound_ = false; 87 is_bound_ = false;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 return right; 133 return right;
137 } 134 }
138 } 135 }
139 136
140 // Otherwise they are incompatible and we will reallocate them. 137 // Otherwise they are incompatible and we will reallocate them.
141 return NULL; 138 return NULL;
142 } 139 }
143 140
144 141
145 void JumpTarget::ComputeEntryFrame(int mergable_elements) { 142 void JumpTarget::ComputeEntryFrame(int mergable_elements) {
146 // Given: a collection of frames reaching by forward CFG edges 143 // Given: a collection of frames reaching by forward CFG edges and
147 // (including the code generator's current frame) and the 144 // the directionality of the block. Compute: an entry frame for the
148 // directionality of the block. Compute: an entry frame for the
149 // block. 145 // block.
150 146
151 // Choose an initial frame, either the code generator's current 147 // Choose an initial frame.
152 // frame if there is one, or the first reaching frame if not. 148 VirtualFrame* initial_frame = reaching_frames_[0];
153 VirtualFrame* initial_frame = cgen_->frame();
154 int start_index = 0; // Begin iteration with the 1st reaching frame.
155 if (initial_frame == NULL) {
156 initial_frame = reaching_frames_[0];
157 start_index = 1; // Begin iteration with the 2nd reaching frame.
158 }
159 149
160 // A list of pointers to frame elements in the entry frame. NULL 150 // A list of pointers to frame elements in the entry frame. NULL
161 // indicates that the element has not yet been determined. 151 // indicates that the element has not yet been determined.
162 int length = initial_frame->elements_.length(); 152 int length = initial_frame->elements_.length();
163 List<FrameElement*> elements(length); 153 List<FrameElement*> elements(length);
164 154
165 // Convert the number of mergable elements (counted from the top 155 // Convert the number of mergable elements (counted from the top
166 // down) to a frame high-water mark (counted from the bottom up). 156 // down) to a frame high-water mark (counted from the bottom up).
167 // Elements strictly above the high-water index will be mergable in 157 // Elements strictly above the high-water index will be mergable in
168 // entry frames for bidirectional jump targets. 158 // entry frames for bidirectional jump targets.
169 int high_water_mark = (mergable_elements == kAllElements) 159 int high_water_mark = (mergable_elements == kAllElements)
170 ? VirtualFrame::kIllegalIndex // All frame indices are above this. 160 ? VirtualFrame::kIllegalIndex // All frame indices are above this.
171 : length - mergable_elements - 1; // Top index if m_e == 0. 161 : length - mergable_elements - 1; // Top index if m_e == 0.
172 162
173 // Initially populate the list of elements based on the initial 163 // Initially populate the list of elements based on the initial
174 // frame. 164 // frame.
175 for (int i = 0; i < length; i++) { 165 for (int i = 0; i < length; i++) {
176 FrameElement element = initial_frame->elements_[i]; 166 FrameElement element = initial_frame->elements_[i];
177 // We do not allow copies or constants in bidirectional frames. 167 // We do not allow copies or constants in bidirectional frames.
178 if (direction_ == BIDIRECTIONAL && 168 if (direction_ == BIDIRECTIONAL &&
179 i > high_water_mark && 169 i > high_water_mark &&
180 (element.is_constant() || element.is_copy())) { 170 (element.is_constant() || element.is_copy())) {
181 elements.Add(NULL); 171 elements.Add(NULL);
182 } else { 172 } else {
183 elements.Add(&initial_frame->elements_[i]); 173 elements.Add(&initial_frame->elements_[i]);
184 } 174 }
185 } 175 }
186 176
187 // Compute elements based on the other reaching frames. 177 // Compute elements based on the other reaching frames.
188 if (start_index < reaching_frames_.length()) { 178 if (reaching_frames_.length() > 1) {
189 for (int i = 0; i < length; i++) { 179 for (int i = 0; i < length; i++) {
190 for (int j = start_index; j < reaching_frames_.length(); j++) { 180 for (int j = 1; j < reaching_frames_.length(); j++) {
191 FrameElement* element = elements[i]; 181 FrameElement* element = elements[i];
192 182
193 // Element computation is monotonic: new information will not 183 // Element computation is monotonic: new information will not
194 // change our decision about undetermined or invalid elements. 184 // change our decision about undetermined or invalid elements.
195 if (element == NULL || !element->is_valid()) break; 185 if (element == NULL || !element->is_valid()) break;
196 186
197 elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]); 187 elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]);
198 } 188 }
199 } 189 }
200 } 190 }
(...skipping 18 matching lines...) Expand all
219 209
220 210
221 // Copy the already-determined frame elements to the entry frame, 211 // Copy the already-determined frame elements to the entry frame,
222 // and allocate any still-undetermined frame elements to registers 212 // and allocate any still-undetermined frame elements to registers
223 // or memory, from the top down. 213 // or memory, from the top down.
224 for (int i = length - 1; i >= 0; i--) { 214 for (int i = length - 1; i >= 0; i--) {
225 if (elements[i] == NULL) { 215 if (elements[i] == NULL) {
226 // If the value is synced on all frames, put it in memory. This 216 // If the value is synced on all frames, put it in memory. This
227 // costs nothing at the merge code but will incur a 217 // costs nothing at the merge code but will incur a
228 // memory-to-register move when the value is needed later. 218 // memory-to-register move when the value is needed later.
229 bool is_synced = initial_frame->elements_[i].is_synced(); 219 bool is_synced = true;
230 int j = start_index; 220 for (int j = 0; is_synced && j < reaching_frames_.length(); j++) {
231 while (is_synced && j < reaching_frames_.length()) {
232 is_synced = reaching_frames_[j]->elements_[i].is_synced(); 221 is_synced = reaching_frames_[j]->elements_[i].is_synced();
233 j++;
234 } 222 }
223
235 // There is nothing to be done if the elements are all synced. 224 // There is nothing to be done if the elements are all synced.
236 // It is already recorded as a memory element. 225 // It is already recorded as a memory element.
237 if (is_synced) continue; 226 if (is_synced) continue;
238 227
239 // Choose an available register. Prefer ones that the element 228 // Choose an available register. Prefer ones that the element
240 // is already occupying on some reaching frame. 229 // is already occupying on some reaching frame.
241 RegisterFile candidate_registers; 230 RegisterFile candidate_registers;
242 int max_count = kMinInt; 231 int max_count = kMinInt;
243 int best_reg_code = no_reg.code_; 232 int best_reg_code = no_reg.code_;
244 233
245 // Consider the initial frame. 234 for (int j = 0; j < reaching_frames_.length(); j++) {
246 FrameElement element = initial_frame->elements_[i]; 235 FrameElement element = reaching_frames_[j]->elements_[i];
247 if (element.is_register() &&
248 !frame_registers.is_used(element.reg())) {
249 candidate_registers.Use(element.reg());
250 max_count = 1;
251 best_reg_code = element.reg().code();
252 }
253 // Consider the other frames.
254 for (int j = start_index; j < reaching_frames_.length(); j++) {
255 element = reaching_frames_[j]->elements_[i];
256 if (element.is_register() && 236 if (element.is_register() &&
257 !frame_registers.is_used(element.reg())) { 237 !frame_registers.is_used(element.reg())) {
258 candidate_registers.Use(element.reg()); 238 candidate_registers.Use(element.reg());
259 if (candidate_registers.count(element.reg()) > max_count) { 239 if (candidate_registers.count(element.reg()) > max_count) {
260 max_count = candidate_registers.count(element.reg()); 240 max_count = candidate_registers.count(element.reg());
261 best_reg_code = element.reg().code(); 241 best_reg_code = element.reg().code();
262 } 242 }
263 } 243 }
264 } 244 }
265 // If there was no preferred choice consider any free register. 245 // If there was no preferred choice consider any free register.
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 } else { 562 } else {
583 JumpTarget::Branch(cc, hint); 563 JumpTarget::Branch(cc, hint);
584 } 564 }
585 } 565 }
586 566
587 567
588 void BreakTarget::Bind(int mergable_elements) { 568 void BreakTarget::Bind(int mergable_elements) {
589 #ifdef DEBUG 569 #ifdef DEBUG
590 ASSERT(mergable_elements == kAllElements); 570 ASSERT(mergable_elements == kAllElements);
591 ASSERT(cgen_ != NULL); 571 ASSERT(cgen_ != NULL);
572 // All the forward-reaching frames should have been adjusted at the
573 // jumps to this target.
592 for (int i = 0; i < reaching_frames_.length(); i++) { 574 for (int i = 0; i < reaching_frames_.length(); i++) {
593 ASSERT(reaching_frames_[i]->height() == expected_height_); 575 ASSERT(reaching_frames_[i] == NULL ||
576 reaching_frames_[i]->height() == expected_height_);
594 } 577 }
595 #endif 578 #endif
596 579 // This is a break target so we drop leftover statement state from
597 // This is a break target so drop leftover statement state from the 580 // the frame before merging, even on the fall through. This is
598 // frame before merging. 581 // because we can bind the return target with state on the frame.
599 if (cgen_->has_valid_frame()) { 582 if (cgen_->has_valid_frame()) {
600 int count = cgen_->frame()->height() - expected_height_; 583 cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_);
601 cgen_->frame()->ForgetElements(count);
602 } 584 }
603 JumpTarget::Bind(mergable_elements); 585 JumpTarget::Bind(mergable_elements);
604 } 586 }
605 587
606 588
607 // ------------------------------------------------------------------------- 589 // -------------------------------------------------------------------------
608 // ShadowTarget implementation. 590 // ShadowTarget implementation.
609 591
610 ShadowTarget::ShadowTarget(BreakTarget* shadowed) { 592 ShadowTarget::ShadowTarget(BreakTarget* shadowed) {
611 ASSERT(shadowed != NULL); 593 ASSERT(shadowed != NULL);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 temp.CopyTo(this); 630 temp.CopyTo(this);
649 temp.Reset(); // So the destructor does not deallocate virtual frames. 631 temp.Reset(); // So the destructor does not deallocate virtual frames.
650 632
651 #ifdef DEBUG 633 #ifdef DEBUG
652 is_shadowing_ = false; 634 is_shadowing_ = false;
653 #endif 635 #endif
654 } 636 }
655 637
656 638
657 } } // namespace v8::internal 639 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/jump-target-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698