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

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

Issue 1961004: First step towards making JumpTarget work on ARM. Instead... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 7 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
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 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 29 matching lines...) Expand all
40 40
41 #define __ ACCESS_MASM(cgen()->masm()) 41 #define __ ACCESS_MASM(cgen()->masm())
42 42
43 void JumpTarget::DoJump() { 43 void JumpTarget::DoJump() {
44 ASSERT(cgen()->has_valid_frame()); 44 ASSERT(cgen()->has_valid_frame());
45 // Live non-frame registers are not allowed at unconditional jumps 45 // Live non-frame registers are not allowed at unconditional jumps
46 // because we have no way of invalidating the corresponding results 46 // because we have no way of invalidating the corresponding results
47 // which are still live in the C++ code. 47 // which are still live in the C++ code.
48 ASSERT(cgen()->HasValidEntryRegisters()); 48 ASSERT(cgen()->HasValidEntryRegisters());
49 49
50 if (is_bound()) { 50 if (entry_frame_set_) {
51 // Backward jump. There already a frame expectation at the target. 51 // There already a frame expectation at the target.
52 ASSERT(direction_ == BIDIRECTIONAL); 52 cgen()->frame()->MergeTo(&entry_frame_);
53 cgen()->frame()->MergeTo(entry_frame_);
54 cgen()->DeleteFrame(); 53 cgen()->DeleteFrame();
55 } else { 54 } else {
56 // Use the current frame as the expected one at the target if necessary. 55 // Use the current frame as the expected one at the target if necessary.
Søren Thygesen Gjesse 2010/05/06 07:48:11 Use the same comment "// Clone the current frame t
57 if (entry_frame_ == NULL) { 56 entry_frame_ = *cgen()->frame();
Søren Thygesen Gjesse 2010/05/06 07:48:11 How about adding a function SetEntryFrame doing
58 entry_frame_ = cgen()->frame(); 57 entry_frame_set_ = true;
59 RegisterFile empty; 58 RegisterFile empty;
60 cgen()->SetFrame(NULL, &empty); 59 cgen()->SetFrame(NULL, &empty);
61 } else {
62 cgen()->frame()->MergeTo(entry_frame_);
63 cgen()->DeleteFrame();
64 }
65
66 // The predicate is_linked() should be made true. Its implementation
67 // detects the presence of a frame pointer in the reaching_frames_ list.
68 if (!is_linked()) {
69 reaching_frames_.Add(NULL);
70 ASSERT(is_linked());
71 }
72 } 60 }
73 __ jmp(&entry_label_); 61 __ jmp(&entry_label_);
74 } 62 }
75 63
76 64
77 void JumpTarget::DoBranch(Condition cc, Hint ignored) { 65 void JumpTarget::DoBranch(Condition cc, Hint ignored) {
78 ASSERT(cgen()->has_valid_frame()); 66 ASSERT(cgen()->has_valid_frame());
79 67
80 if (is_bound()) { 68 if (entry_frame_set_) {
81 ASSERT(direction_ == BIDIRECTIONAL);
82 // Backward branch. We have an expected frame to merge to on the 69 // Backward branch. We have an expected frame to merge to on the
83 // backward edge. 70 // backward edge.
84 cgen()->frame()->MergeTo(entry_frame_); 71 if (cc == al) {
72 cgen()->frame()->MergeTo(&entry_frame_);
73 } else {
74 // We can't do conditional merges yet so you have to ensure that all
75 // conditional branches to the JumpTarget have the same virtual frame.
76 ASSERT(cgen()->frame()->Equals(&entry_frame_));
77 }
85 } else { 78 } else {
86 // Clone the current frame to use as the expected one at the target if 79 // Clone the current frame to use as the expected one at the target.
87 // necessary. 80 entry_frame_ = *cgen()->frame();
88 if (entry_frame_ == NULL) { 81 entry_frame_set_ = true;
89 entry_frame_ = new VirtualFrame(cgen()->frame());
90 }
91 // The predicate is_linked() should be made true. Its implementation
92 // detects the presence of a frame pointer in the reaching_frames_ list.
93 if (!is_linked()) {
94 reaching_frames_.Add(NULL);
95 ASSERT(is_linked());
96 }
97 } 82 }
98 __ b(cc, &entry_label_); 83 __ b(cc, &entry_label_);
99 } 84 }
100 85
101 86
102 void JumpTarget::Call() { 87 void JumpTarget::Call() {
103 // Call is used to push the address of the catch block on the stack as 88 // Call is used to push the address of the catch block on the stack as
104 // a return address when compiling try/catch and try/finally. We 89 // a return address when compiling try/catch and try/finally. We
105 // fully spill the frame before making the call. The expected frame 90 // fully spill the frame before making the call. The expected frame
106 // at the label (which should be the only one) is the spilled current 91 // at the label (which should be the only one) is the spilled current
107 // frame plus an in-memory return address. The "fall-through" frame 92 // frame plus an in-memory return address. The "fall-through" frame
108 // at the return site is the spilled current frame. 93 // at the return site is the spilled current frame.
109 ASSERT(cgen()->has_valid_frame()); 94 ASSERT(cgen()->has_valid_frame());
110 // There are no non-frame references across the call. 95 // There are no non-frame references across the call.
111 ASSERT(cgen()->HasValidEntryRegisters()); 96 ASSERT(cgen()->HasValidEntryRegisters());
112 ASSERT(!is_linked()); 97 ASSERT(!is_linked());
113 98
114 // Calls are always 'forward' so we use a copy of the current frame (plus 99 // Calls are always 'forward' so we use a copy of the current frame (plus
115 // one for a return address) as the expected frame. 100 // one for a return address) as the expected frame.
116 ASSERT(entry_frame_ == NULL); 101 ASSERT(!entry_frame_set_);
117 VirtualFrame* target_frame = new VirtualFrame(cgen()->frame()); 102 VirtualFrame target_frame = *cgen()->frame();
118 target_frame->Adjust(1); 103 target_frame.Adjust(1);
119 entry_frame_ = target_frame; 104 entry_frame_ = target_frame;
120 105 entry_frame_set_ = true;
121 // The predicate is_linked() should now be made true. Its implementation
122 // detects the presence of a frame pointer in the reaching_frames_ list.
123 reaching_frames_.Add(NULL);
124 ASSERT(is_linked());
125 106
126 __ bl(&entry_label_); 107 __ bl(&entry_label_);
127 } 108 }
128 109
129 110
130 void JumpTarget::DoBind() { 111 void JumpTarget::DoBind() {
131 ASSERT(!is_bound()); 112 ASSERT(!is_bound());
132 113
133 // Live non-frame registers are not allowed at the start of a basic 114 // Live non-frame registers are not allowed at the start of a basic
134 // block. 115 // block.
135 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters()); 116 ASSERT(!cgen()->has_valid_frame() || cgen()->HasValidEntryRegisters());
136 117
137 if (cgen()->has_valid_frame()) { 118 if (cgen()->has_valid_frame()) {
138 // If there is a current frame we can use it on the fall through. 119 // If there is a current frame we can use it on the fall through.
139 if (entry_frame_ == NULL) { 120 if (!entry_frame_set_) {
140 entry_frame_ = new VirtualFrame(cgen()->frame()); 121 entry_frame_ = *cgen()->frame();
122 entry_frame_set_ = true;
141 } else { 123 } else {
142 ASSERT(cgen()->frame()->Equals(entry_frame_)); 124 cgen()->frame()->MergeTo(&entry_frame_);
143 } 125 }
144 } else { 126 } else {
145 // If there is no current frame we must have an entry frame which we can 127 // If there is no current frame we must have an entry frame which we can
146 // copy. 128 // copy.
147 ASSERT(entry_frame_ != NULL); 129 ASSERT(entry_frame_set_);
148 RegisterFile empty; 130 RegisterFile empty;
149 cgen()->SetFrame(new VirtualFrame(entry_frame_), &empty); 131 cgen()->SetFrame(new VirtualFrame(&entry_frame_), &empty);
150 }
151
152 // The predicate is_linked() should be made false. Its implementation
153 // detects the presence (or absence) of frame pointers in the
154 // reaching_frames_ list. If we inserted a bogus frame to make
155 // is_linked() true, remove it now.
156 if (is_linked()) {
157 reaching_frames_.Clear();
158 } 132 }
159 133
160 __ bind(&entry_label_); 134 __ bind(&entry_label_);
161 } 135 }
162 136
163 137
164 void BreakTarget::Jump() {
165 // On ARM we do not currently emit merge code for jumps, so we need to do
166 // it explicitly here. The only merging necessary is to drop extra
167 // statement state from the stack.
168 ASSERT(cgen()->has_valid_frame());
169 int count = cgen()->frame()->height() - expected_height_;
170 cgen()->frame()->Drop(count);
171 DoJump();
172 }
173
174
175 void BreakTarget::Jump(Result* arg) {
176 UNIMPLEMENTED();
177 }
178
179
180 void BreakTarget::Bind() {
181 #ifdef DEBUG
182 // All the forward-reaching frames should have been adjusted at the
183 // jumps to this target.
184 for (int i = 0; i < reaching_frames_.length(); i++) {
185 ASSERT(reaching_frames_[i] == NULL ||
186 reaching_frames_[i]->height() == expected_height_);
187 }
188 #endif
189 // Drop leftover statement state from the frame before merging, even
190 // on the fall through. This is so we can bind the return target
191 // with state on the frame.
192 if (cgen()->has_valid_frame()) {
193 int count = cgen()->frame()->height() - expected_height_;
194 // On ARM we do not currently emit merge code at binding sites, so we need
195 // to do it explicitly here. The only merging necessary is to drop extra
196 // statement state from the stack.
197 cgen()->frame()->Drop(count);
198 }
199
200 DoBind();
201 }
202
203
204 void BreakTarget::Bind(Result* arg) {
205 UNIMPLEMENTED();
206 }
207
208
209 #undef __ 138 #undef __
210 139
211 140
212 } } // namespace v8::internal 141 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698