| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 74 | 74 | 
| 75   // A list of pointers to frame elements in the entry frame.  NULL | 75   // A list of pointers to frame elements in the entry frame.  NULL | 
| 76   // indicates that the element has not yet been determined. | 76   // indicates that the element has not yet been determined. | 
| 77   int length = initial_frame->element_count(); | 77   int length = initial_frame->element_count(); | 
| 78   ZoneList<FrameElement*> elements(length); | 78   ZoneList<FrameElement*> elements(length); | 
| 79 | 79 | 
| 80   // Initially populate the list of elements based on the initial | 80   // Initially populate the list of elements based on the initial | 
| 81   // frame. | 81   // frame. | 
| 82   for (int i = 0; i < length; i++) { | 82   for (int i = 0; i < length; i++) { | 
| 83     FrameElement element = initial_frame->elements_[i]; | 83     FrameElement element = initial_frame->elements_[i]; | 
| 84     // We do not allow copies or constants in bidirectional frames.  All | 84     // We do not allow copies or constants in bidirectional frames. | 
| 85     // elements above the water mark on bidirectional frames have |  | 
| 86     // unknown static types. |  | 
| 87     if (direction_ == BIDIRECTIONAL) { | 85     if (direction_ == BIDIRECTIONAL) { | 
| 88       if (element.is_constant() || element.is_copy()) { | 86       if (element.is_constant() || element.is_copy()) { | 
| 89         elements.Add(NULL); | 87         elements.Add(NULL); | 
| 90         continue; | 88         continue; | 
| 91       } | 89       } | 
| 92       // It's safe to change the static type on the initial frame |  | 
| 93       // element, see comment in JumpTarget::Combine. |  | 
| 94       initial_frame->elements_[i].set_static_type(StaticType::unknown()); |  | 
| 95     } | 90     } | 
| 96     elements.Add(&initial_frame->elements_[i]); | 91     elements.Add(&initial_frame->elements_[i]); | 
| 97   } | 92   } | 
| 98 | 93 | 
| 99   // Compute elements based on the other reaching frames. | 94   // Compute elements based on the other reaching frames. | 
| 100   if (reaching_frames_.length() > 1) { | 95   if (reaching_frames_.length() > 1) { | 
| 101     for (int i = 0; i < length; i++) { | 96     for (int i = 0; i < length; i++) { | 
| 102       FrameElement* element = elements[i]; | 97       FrameElement* element = elements[i]; | 
| 103       for (int j = 1; j < reaching_frames_.length(); j++) { | 98       for (int j = 1; j < reaching_frames_.length(); j++) { | 
| 104         // Element computation is monotonic: new information will not | 99         // Element computation is monotonic: new information will not | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 135       entry_frame_->elements_.Add(*target); | 130       entry_frame_->elements_.Add(*target); | 
| 136       InitializeEntryElement(index, target); | 131       InitializeEntryElement(index, target); | 
| 137     } | 132     } | 
| 138   } | 133   } | 
| 139 | 134 | 
| 140   // Allocate any still-undetermined frame elements to registers or | 135   // Allocate any still-undetermined frame elements to registers or | 
| 141   // memory, from the top down. | 136   // memory, from the top down. | 
| 142   for (int i = length - 1; i >= 0; i--) { | 137   for (int i = length - 1; i >= 0; i--) { | 
| 143     if (elements[i] == NULL) { | 138     if (elements[i] == NULL) { | 
| 144       // Loop over all the reaching frames to check whether the element | 139       // Loop over all the reaching frames to check whether the element | 
| 145       // is synced on all frames, to count the registers it occupies, | 140       // is synced on all frames and to count the registers it occupies. | 
| 146       // and to compute a merged static type. |  | 
| 147       bool is_synced = true; | 141       bool is_synced = true; | 
| 148       RegisterFile candidate_registers; | 142       RegisterFile candidate_registers; | 
| 149       int best_count = kMinInt; | 143       int best_count = kMinInt; | 
| 150       int best_reg_num = RegisterAllocator::kInvalidRegister; | 144       int best_reg_num = RegisterAllocator::kInvalidRegister; | 
| 151 | 145 | 
| 152       StaticType type;  // Initially invalid. |  | 
| 153       if (direction_ != BIDIRECTIONAL) { |  | 
| 154         type = reaching_frames_[0]->elements_[i].static_type(); |  | 
| 155       } |  | 
| 156 |  | 
| 157       for (int j = 0; j < reaching_frames_.length(); j++) { | 146       for (int j = 0; j < reaching_frames_.length(); j++) { | 
| 158         FrameElement element = reaching_frames_[j]->elements_[i]; | 147         FrameElement element = reaching_frames_[j]->elements_[i]; | 
| 159         is_synced = is_synced && element.is_synced(); | 148         is_synced = is_synced && element.is_synced(); | 
| 160         if (element.is_register() && !entry_frame_->is_used(element.reg())) { | 149         if (element.is_register() && !entry_frame_->is_used(element.reg())) { | 
| 161           // Count the register occurrence and remember it if better | 150           // Count the register occurrence and remember it if better | 
| 162           // than the previous best. | 151           // than the previous best. | 
| 163           int num = RegisterAllocator::ToNumber(element.reg()); | 152           int num = RegisterAllocator::ToNumber(element.reg()); | 
| 164           candidate_registers.Use(num); | 153           candidate_registers.Use(num); | 
| 165           if (candidate_registers.count(num) > best_count) { | 154           if (candidate_registers.count(num) > best_count) { | 
| 166             best_count = candidate_registers.count(num); | 155             best_count = candidate_registers.count(num); | 
| 167             best_reg_num = num; | 156             best_reg_num = num; | 
| 168           } | 157           } | 
| 169         } | 158         } | 
| 170         type = type.merge(element.static_type()); |  | 
| 171       } | 159       } | 
| 172 | 160 | 
| 173       // If the value is synced on all frames, put it in memory.  This | 161       // If the value is synced on all frames, put it in memory.  This | 
| 174       // costs nothing at the merge code but will incur a | 162       // costs nothing at the merge code but will incur a | 
| 175       // memory-to-register move when the value is needed later. | 163       // memory-to-register move when the value is needed later. | 
| 176       if (is_synced) { | 164       if (is_synced) { | 
| 177         // Already recorded as a memory element. | 165         // Already recorded as a memory element. | 
| 178         entry_frame_->elements_[i].set_static_type(type); |  | 
| 179         continue; | 166         continue; | 
| 180       } | 167       } | 
| 181 | 168 | 
| 182       // Try to put it in a register.  If there was no best choice | 169       // Try to put it in a register.  If there was no best choice | 
| 183       // consider any free register. | 170       // consider any free register. | 
| 184       if (best_reg_num == RegisterAllocator::kInvalidRegister) { | 171       if (best_reg_num == RegisterAllocator::kInvalidRegister) { | 
| 185         for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { | 172         for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { | 
| 186           if (!entry_frame_->is_used(j)) { | 173           if (!entry_frame_->is_used(j)) { | 
| 187             best_reg_num = j; | 174             best_reg_num = j; | 
| 188             break; | 175             break; | 
| 189           } | 176           } | 
| 190         } | 177         } | 
| 191       } | 178       } | 
| 192 | 179 | 
| 193       if (best_reg_num == RegisterAllocator::kInvalidRegister) { | 180       if (best_reg_num != RegisterAllocator::kInvalidRegister) { | 
| 194         // If there was no register found, the element is already |  | 
| 195         // recorded as in memory. |  | 
| 196         entry_frame_->elements_[i].set_static_type(type); |  | 
| 197       } else { |  | 
| 198         // If there was a register choice, use it.  Preserve the copied | 181         // If there was a register choice, use it.  Preserve the copied | 
| 199         // flag on the element.  Set the static type as computed. | 182         // flag on the element. | 
| 200         bool is_copied = entry_frame_->elements_[i].is_copied(); | 183         bool is_copied = entry_frame_->elements_[i].is_copied(); | 
| 201         Register reg = RegisterAllocator::ToRegister(best_reg_num); | 184         Register reg = RegisterAllocator::ToRegister(best_reg_num); | 
| 202         entry_frame_->elements_[i] = | 185         entry_frame_->elements_[i] = | 
| 203             FrameElement::RegisterElement(reg, | 186             FrameElement::RegisterElement(reg, | 
| 204                                           FrameElement::NOT_SYNCED); | 187                                           FrameElement::NOT_SYNCED); | 
| 205         if (is_copied) entry_frame_->elements_[i].set_copied(); | 188         if (is_copied) entry_frame_->elements_[i].set_copied(); | 
| 206         entry_frame_->elements_[i].set_static_type(type); |  | 
| 207         entry_frame_->set_register_location(reg, i); | 189         entry_frame_->set_register_location(reg, i); | 
| 208       } | 190       } | 
| 209     } | 191     } | 
| 210   } | 192   } | 
| 211 | 193 | 
| 212   // The stack pointer is at the highest synced element or the base of | 194   // The stack pointer is at the highest synced element or the base of | 
| 213   // the expression stack. | 195   // the expression stack. | 
| 214   int stack_pointer = length - 1; | 196   int stack_pointer = length - 1; | 
| 215   while (stack_pointer >= entry_frame_->expression_base_index() && | 197   while (stack_pointer >= entry_frame_->expression_base_index() && | 
| 216          !entry_frame_->elements_[stack_pointer].is_synced()) { | 198          !entry_frame_->elements_[stack_pointer].is_synced()) { | 
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 453   temp.CopyTo(this); | 435   temp.CopyTo(this); | 
| 454   temp.Unuse(); | 436   temp.Unuse(); | 
| 455 | 437 | 
| 456 #ifdef DEBUG | 438 #ifdef DEBUG | 
| 457   is_shadowing_ = false; | 439   is_shadowing_ = false; | 
| 458 #endif | 440 #endif | 
| 459 } | 441 } | 
| 460 | 442 | 
| 461 | 443 | 
| 462 } }  // namespace v8::internal | 444 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|