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

Unified Diff: src/jump-target-arm.cc

Issue 21505: Experimental: port the code to avoid silly merges from IA32 to ARM.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/jump-target-arm.cc
===================================================================
--- src/jump-target-arm.cc (revision 1298)
+++ src/jump-target-arm.cc (working copy)
@@ -142,40 +142,94 @@
ComputeEntryFrame(mergable_elements);
if (is_linked()) {
- // There were forward jumps. All the reaching frames, beginning
- // with the current frame if any, are merged to the expected one.
- int start_index = 0;
- if (!cgen_->has_valid_frame()) {
- // Pick up the first reaching frame as the code generator's
- // current frame.
- RegisterFile reserved_registers = RegisterAllocator::Reserved();
- cgen_->SetFrame(reaching_frames_[0], &reserved_registers);
- __ bind(&merge_labels_[0]);
- start_index = 1;
+ // There were forward jumps. Handle merging the reaching frames
+ // and possible fall through to the entry frame.
+
+ // If there is a fall through to the jump target and it needs
+ // merge code, process it first.
+ if (cgen_->has_valid_frame() && !cgen_->frame()->Equals(entry_frame_)) {
+ // Loop over all the reaching frames, looking for any that can
+ // share merge code with this one.
+ for (int i = 0; i < reaching_frames_.length(); i++) {
+ if (cgen_->frame()->Equals(reaching_frames_[i])) {
+ // Set the reaching frames element to null to avoid
+ // processing it later, and then bind its entry label.
+ delete reaching_frames_[i];
+ reaching_frames_[i] = NULL;
+ __ bind(&merge_labels_[i]);
+ }
+ }
+
+ // Emit the merge code.
+ cgen_->frame()->MergeTo(entry_frame_);
}
- cgen_->frame()->MergeTo(entry_frame_);
+ // Loop over the (non-null) reaching frames and process any that
+ // need merge code.
+ for (int i = 0; i < reaching_frames_.length(); i++) {
+ VirtualFrame* frame = reaching_frames_[i];
+ if (frame != NULL && !frame->Equals(entry_frame_)) {
+ // Set the reaching frames element to null to avoid processing
+ // it later. Do not delete it as it is needed for merging.
+ reaching_frames_[i] = NULL;
- for (int i = start_index; i < reaching_frames_.length(); i++) {
- // Delete the current frame and jump to the block entry.
- cgen_->DeleteFrame();
- __ jmp(&entry_label_);
+ // If the code generator has a current frame (a fall-through
+ // or a previously merged frame), insert a jump around the
+ // merge code we are about to generate.
+ if (cgen_->has_valid_frame()) {
+ cgen_->DeleteFrame();
+ __ jmp(&entry_label_);
+ }
- // Pick up the next reaching frame as the code generator's
- // current frame.
- RegisterFile reserved_registers = RegisterAllocator::Reserved();
- cgen_->SetFrame(reaching_frames_[i], &reserved_registers);
- __ bind(&merge_labels_[i]);
+ // Set the frame to merge as the code generator's current
+ // frame and bind its merge label.
+ RegisterFile reserved_registers = RegisterAllocator::Reserved();
+ cgen_->SetFrame(frame, &reserved_registers);
+ __ bind(&merge_labels_[i]);
- cgen_->frame()->MergeTo(entry_frame_);
+ // Loop over the remaining (non-null) reaching frames, looking
+ // for any that can share merge code with this one.
+ for (int j = i + 1; j < reaching_frames_.length(); j++) {
+ VirtualFrame* other = reaching_frames_[j];
+ if (other != NULL && frame->Equals(other)) {
+ delete other;
+ reaching_frames_[j] = NULL;
+ __ bind(&merge_labels_[j]);
+ }
+ }
+
+ // Emit the merge code.
+ cgen_->frame()->MergeTo(entry_frame_);
+ }
}
+ // The code generator may not have a current frame if there was no
+ // fall through and none of the reaching frames needed merging.
+ // In that case, clone the entry frame as the current frame.
+ if (!cgen_->has_valid_frame()) {
+ RegisterFile reserved_registers = RegisterAllocator::Reserved();
+ cgen_->SetFrame(new VirtualFrame(entry_frame_), &reserved_registers);
+ }
+
+ // There is certainly a current frame equal to the entry frame.
+ // Bind the entry frame label.
__ bind(&entry_label_);
- // All but the last reaching virtual frame have been deleted, and
- // the last one is the current frame.
+ // There may be unprocessed reaching frames that did not need
+ // merge code. Bind their merge labels to be the same as the
+ // entry label.
+ for (int i = 0; i < reaching_frames_.length(); i++) {
+ if (reaching_frames_[i] != NULL) {
+ delete reaching_frames_[i];
+ __ bind(&merge_labels_[i]);
+ }
+ }
+
+ // All the reaching frames except the one that is the current
+ // frame (if it is one of the reaching frames) have been deleted.
reaching_frames_.Clear();
merge_labels_.Clear();
+
} else {
// There were no forward jumps. The current frame is merged to
// the entry frame.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698