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

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

Issue 15079: Experimental: this is a substantial change to allow the virtual frame... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 12 years 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 21 matching lines...) Expand all
32 32
33 namespace v8 { namespace internal { 33 namespace v8 { namespace internal {
34 34
35 // ------------------------------------------------------------------------- 35 // -------------------------------------------------------------------------
36 // JumpTarget implementation. 36 // JumpTarget implementation.
37 37
38 #define __ masm_-> 38 #define __ masm_->
39 39
40 JumpTarget::JumpTarget(CodeGenerator* cgen) 40 JumpTarget::JumpTarget(CodeGenerator* cgen)
41 : expected_frame_(NULL), 41 : expected_frame_(NULL),
42 code_generator_(cgen), 42 cgen_(cgen),
43 masm_(cgen->masm()) { 43 masm_(cgen->masm()) {
44 } 44 }
45 45
46 46
47 JumpTarget::JumpTarget() 47 JumpTarget::JumpTarget()
48 : expected_frame_(NULL), 48 : expected_frame_(NULL),
49 code_generator_(NULL), 49 cgen_(NULL),
50 masm_(NULL) { 50 masm_(NULL) {
51 } 51 }
52 52
53 53
54 void JumpTarget::set_code_generator(CodeGenerator* cgen) { 54 void JumpTarget::set_code_generator(CodeGenerator* cgen) {
55 ASSERT(cgen != NULL); 55 ASSERT(cgen != NULL);
56 ASSERT(code_generator_ == NULL); 56 ASSERT(cgen_ == NULL);
57 code_generator_ = cgen; 57 cgen_ = cgen;
58 masm_ = cgen->masm(); 58 masm_ = cgen->masm();
59 } 59 }
60 60
61 61
62 void JumpTarget::Jump() { 62 void JumpTarget::Jump() {
63 // Precondition: there is a current frame. There may or may not be an 63 // Precondition: there is a current frame. There may or may not be an
64 // expected frame at the label. 64 // expected frame at the label.
65 ASSERT(code_generator_ != NULL); 65 ASSERT(cgen_ != NULL);
66 66
67 VirtualFrame* current_frame = code_generator_->frame(); 67 VirtualFrame* current_frame = cgen_->frame();
68 ASSERT(current_frame != NULL); 68 ASSERT(current_frame != NULL);
69 ASSERT(cgen_->HasValidEntryRegisters());
69 70
70 if (expected_frame_ == NULL) { 71 if (expected_frame_ == NULL) {
71 // The frame at the actual function return will always have height zero. 72 // The frame at the actual function return will always have height zero.
72 if (code_generator_->IsActualFunctionReturn(this)) { 73 if (cgen_->IsActualFunctionReturn(this)) {
73 current_frame->Forget(current_frame->height()); 74 current_frame->Forget(current_frame->height());
74 } 75 }
75 if (!current_frame->IsMergable()) { 76 current_frame->MakeMergable();
76 current_frame->MakeMergable();
77 }
78 expected_frame_ = current_frame; 77 expected_frame_ = current_frame;
79 code_generator_->SetFrame(NULL); 78 ASSERT(cgen_->HasValidEntryRegisters());
79 cgen_->SetFrame(NULL);
80 } else { 80 } else {
81 // No code needs to be emitted to merge to the expected frame at the 81 // No code needs to be emitted to merge to the expected frame at the
82 // actual function return. 82 // actual function return.
83 if (!code_generator_->IsActualFunctionReturn(this)) { 83 if (!cgen_->IsActualFunctionReturn(this)) {
84 current_frame->MergeTo(expected_frame_); 84 current_frame->MergeTo(expected_frame_);
85 } 85 }
86 code_generator_->DeleteFrame(); 86 ASSERT(cgen_->HasValidEntryRegisters());
87 cgen_->DeleteFrame();
87 } 88 }
88 89
89 __ jmp(&label_); 90 __ jmp(&label_);
90 // Postcondition: there is no current frame but there is an expected frame 91 // Postcondition: there is no current frame but there is an expected frame
91 // at the label. 92 // at the label.
92 } 93 }
93 94
94 95
95 void JumpTarget::Branch(Condition cc, Hint hint) { 96 void JumpTarget::Branch(Condition cc, Hint hint) {
96 // Precondition: there is a current frame. There may or may not be an 97 // Precondition: there is a current frame. There may or may not be an
97 // expected frame at the label. 98 // expected frame at the label.
98 ASSERT(code_generator_ != NULL); 99 ASSERT(cgen_ != NULL);
99 ASSERT(masm_ != NULL); 100 ASSERT(masm_ != NULL);
100 101
101 VirtualFrame* current_frame = code_generator_->frame(); 102 VirtualFrame* current_frame = cgen_->frame();
102 ASSERT(current_frame != NULL); 103 ASSERT(current_frame != NULL);
104 ASSERT(cgen_->HasValidEntryRegisters());
103 105
104 if (expected_frame_ == NULL) { 106 if (expected_frame_ == NULL) {
105 expected_frame_ = new VirtualFrame(current_frame); 107 expected_frame_ = new VirtualFrame(current_frame);
106 // The frame at the actual function return will always have height zero. 108 // The frame at the actual function return will always have height zero.
107 if (code_generator_->IsActualFunctionReturn(this)) { 109 if (cgen_->IsActualFunctionReturn(this)) {
108 expected_frame_->Forget(expected_frame_->height()); 110 expected_frame_->Forget(expected_frame_->height());
109 } 111 }
110 // For a branch, the frame at the fall-through basic block (not labeled) 112 // For a branch, the frame at the fall-through basic block (not labeled)
111 // does not need to be mergable, but only the other (labeled) one. That 113 // does not need to be mergable, but only the other (labeled) one. That
112 // is achieved by reversing the condition and emitting the make mergable 114 // is achieved by reversing the condition and emitting the make mergable
113 // code as the actual fall-through block. This is necessary only when 115 // code as the actual fall-through block. This is necessary only when
114 // MakeMergable will generate code. 116 // MakeMergable will generate code.
115 if (expected_frame_->RequiresMergeCode()) { 117 if (expected_frame_->RequiresMergeCode()) {
116 Label original_fall_through; 118 Label original_fall_through;
117 __ j(NegateCondition(cc), &original_fall_through, NegateHint(hint)); 119 __ j(NegateCondition(cc), &original_fall_through, NegateHint(hint));
118 expected_frame_->MakeMergable(); 120 expected_frame_->MakeMergable();
119 __ jmp(&label_); 121 __ jmp(&label_);
120 __ bind(&original_fall_through); 122 __ bind(&original_fall_through);
121 } else { 123 } else {
122 if (!expected_frame_->IsMergable()) { 124 expected_frame_->MakeMergable();
123 expected_frame_->MakeMergable(); 125 ASSERT(cgen_->HasValidEntryRegisters());
124 }
125 __ j(cc, &label_, hint); 126 __ j(cc, &label_, hint);
126 } 127 }
127 } else { 128 } else {
128 // No code needs to be emitted to merge to the expected frame at the 129 // No code needs to be emitted to merge to the expected frame at the
129 // actual function return. 130 // actual function return.
130 if (!code_generator_->IsActualFunctionReturn(this)) { 131 if (!cgen_->IsActualFunctionReturn(this)) {
131 current_frame->MergeTo(expected_frame_); 132 current_frame->MergeTo(expected_frame_);
132 } 133 }
134 ASSERT(cgen_->HasValidEntryRegisters());
133 __ j(cc, &label_, hint); 135 __ j(cc, &label_, hint);
134 } 136 }
135 // Postcondition: there is both a current frame and an expected frame at 137 // Postcondition: there is both a current frame and an expected frame at
136 // the label and they match. 138 // the label and they match.
137 } 139 }
138 140
139 141
142 void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) {
143 ASSERT(cgen_ != NULL);
144 ASSERT(cgen_->frame() != NULL);
145
146 #ifdef DEBUG
147 // We want register results at the call site to stay in the same registers
148 // on the fall-through branch.
149 Result::Type arg_type = arg->type();
150 Register arg_reg = arg->is_register() ? arg->reg() : no_reg;
151 #endif
152
153 cgen_->frame()->Push(arg);
154 Branch(cc, hint);
155 *arg = cgen_->frame()->Pop();
156
157 ASSERT(arg->type() == arg_type);
158 ASSERT(!arg->is_register() || arg->reg().is(arg_reg));
159 }
160
161
140 void JumpTarget::Call() { 162 void JumpTarget::Call() {
141 // Precondition: there is a current frame, and there is no expected frame 163 // Precondition: there is a current frame, and there is no expected frame
142 // at the label. 164 // at the label.
143 ASSERT(code_generator_ != NULL); 165 ASSERT(cgen_ != NULL);
144 ASSERT(masm_ != NULL); 166 ASSERT(masm_ != NULL);
145 ASSERT(!code_generator_->IsActualFunctionReturn(this)); 167 ASSERT(!cgen_->IsActualFunctionReturn(this));
146 168
147 VirtualFrame* current_frame = code_generator_->frame(); 169 VirtualFrame* current_frame = cgen_->frame();
148 ASSERT(current_frame != NULL); 170 ASSERT(current_frame != NULL);
149 ASSERT(expected_frame_ == NULL); 171 ASSERT(expected_frame_ == NULL);
172 ASSERT(cgen_->HasValidEntryRegisters());
150 173
151 expected_frame_ = new VirtualFrame(current_frame); 174 expected_frame_ = new VirtualFrame(current_frame);
152 if (!expected_frame_->IsMergable()) { 175 expected_frame_->MakeMergable();
153 expected_frame_->MakeMergable();
154 }
155 // Adjust the expected frame's height to account for the return address 176 // Adjust the expected frame's height to account for the return address
156 // pushed by the call instruction. 177 // pushed by the call instruction.
157 expected_frame_->Adjust(1); 178 expected_frame_->Adjust(1);
179 ASSERT(cgen_->HasValidEntryRegisters());
158 180
159 __ call(&label_); 181 __ call(&label_);
160 // Postcondition: there is both a current frame and an expected frame at 182 // Postcondition: there is both a current frame and an expected frame at
161 // the label. The current frame is one shorter than the one at the label 183 // the label. The current frame is one shorter than the one at the label
162 // (which contains the return address in memory). 184 // (which contains the return address in memory).
163 } 185 }
164 186
165 187
166 void JumpTarget::Bind() { 188 void JumpTarget::Bind() {
167 // Precondition: there is either a current frame or an expected frame at 189 // Precondition: there is either a current frame or an expected frame at
168 // the label (and possibly both). The label is unbound. 190 // the label (and possibly both). The label is unbound.
169 ASSERT(code_generator_ != NULL); 191 ASSERT(cgen_ != NULL);
170 ASSERT(masm_ != NULL); 192 ASSERT(masm_ != NULL);
171 193
172 VirtualFrame* current_frame = code_generator_->frame(); 194 VirtualFrame* current_frame = cgen_->frame();
173 ASSERT(current_frame != NULL || expected_frame_ != NULL); 195 ASSERT(current_frame != NULL || expected_frame_ != NULL);
174 ASSERT(!label_.is_bound()); 196 ASSERT(!label_.is_bound());
175 197
176 if (expected_frame_ == NULL) { 198 if (expected_frame_ == NULL) {
199 ASSERT(cgen_->HasValidEntryRegisters());
177 // When a label is bound the current frame becomes the expected frame at 200 // When a label is bound the current frame becomes the expected frame at
178 // the label. This requires the current frame to be mergable. 201 // the label. This requires the current frame to be mergable.
179 // The frame at the actual function return will always have height zero. 202 // The frame at the actual function return will always have height zero.
180 if (code_generator_->IsActualFunctionReturn(this)) { 203 if (cgen_->IsActualFunctionReturn(this)) {
181 current_frame->Forget(current_frame->height()); 204 current_frame->Forget(current_frame->height());
182 } 205 }
183 if (!current_frame->IsMergable()) { 206 current_frame->MakeMergable();
184 current_frame->MakeMergable(); 207 ASSERT(cgen_->HasValidEntryRegisters());
185 }
186 expected_frame_ = new VirtualFrame(current_frame); 208 expected_frame_ = new VirtualFrame(current_frame);
187 } else if (current_frame == NULL) { 209 } else if (current_frame == NULL) {
188 code_generator_->SetFrame(new VirtualFrame(expected_frame_)); 210 cgen_->SetFrame(new VirtualFrame(expected_frame_));
211 ASSERT(cgen_->HasValidEntryRegisters());
189 } else { 212 } else {
213 ASSERT(cgen_->HasValidEntryRegisters());
190 // No code needs to be emitted to merge to the expected frame at the 214 // No code needs to be emitted to merge to the expected frame at the
191 // actual function return. 215 // actual function return.
192 if (!code_generator_->IsActualFunctionReturn(this)) { 216 if (!cgen_->IsActualFunctionReturn(this)) {
193 current_frame->MergeTo(expected_frame_); 217 current_frame->MergeTo(expected_frame_);
194 } 218 }
219 ASSERT(cgen_->HasValidEntryRegisters());
195 } 220 }
196 221
197 __ bind(&label_); 222 __ bind(&label_);
198 // Postcondition: there is both a current frame and an expected frame at 223 // Postcondition: there is both a current frame and an expected frame at
199 // the label and they match. The label is bound. 224 // the label and they match. The label is bound.
200 } 225 }
201 226
202 227
228 void JumpTarget::Bind(Result* arg) {
229 ASSERT(cgen_ != NULL);
230
231 #ifdef DEBUG
232 // We want register results at the call site to stay in the same
233 // registers.
234 bool had_entry_frame = false;
235 Result::Type arg_type;
236 Register arg_reg;
237 #endif
238
239 if (cgen_->frame() != NULL) {
240 #ifdef DEBUG
241 had_entry_frame = true;
242 arg_type = arg->type();
243 arg_reg = arg->is_register() ? arg->reg() : no_reg;
244 #endif
245 cgen_->frame()->Push(arg);
246 }
247 Bind();
248 *arg = cgen_->frame()->Pop();
249
250 ASSERT(!had_entry_frame || arg->type() == arg_type);
251 ASSERT(!had_entry_frame || !arg->is_register() || arg->reg().is(arg_reg));
252 }
253
254
203 // ------------------------------------------------------------------------- 255 // -------------------------------------------------------------------------
204 // ShadowTarget implementation. 256 // ShadowTarget implementation.
205 257
206 ShadowTarget::ShadowTarget(JumpTarget* original) { 258 ShadowTarget::ShadowTarget(JumpTarget* original) {
207 ASSERT(original != NULL); 259 ASSERT(original != NULL);
208 original_target_ = original; 260 original_target_ = original;
209 original_pos_ = original->label()->pos_; 261 original_pos_ = original->label()->pos_;
210 original_expected_frame_ = original->expected_frame(); 262 original_expected_frame_ = original->expected_frame();
211 263
212 // We do not call Unuse() on the orginal jump target, because we do not 264 // We do not call Unuse() on the orginal jump target, because we do not
(...skipping 19 matching lines...) Expand all
232 284
233 #ifdef DEBUG 285 #ifdef DEBUG
234 is_shadowing_ = false; 286 is_shadowing_ = false;
235 #endif 287 #endif
236 } 288 }
237 289
238 #undef __ 290 #undef __
239 291
240 292
241 } } // namespace v8::internal 293 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jump-target.h ('k') | src/register-allocator-ia32.h » ('j') | src/register-allocator-ia32.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698