| OLD | NEW |
| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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(cgen_ != NULL); | 65 ASSERT(cgen_ != NULL); |
| 66 | 66 |
| 67 VirtualFrame* current_frame = cgen_->frame(); | 67 VirtualFrame* current_frame = cgen_->frame(); |
| 68 ASSERT(current_frame != NULL); | 68 ASSERT(current_frame != NULL); |
| 69 ASSERT(cgen_->HasValidEntryRegisters()); | 69 ASSERT(cgen_->HasValidEntryRegisters()); |
| 70 | 70 |
| 71 if (expected_frame_ == NULL) { | 71 if (expected_frame_ == NULL) { |
| 72 // The frame at the actual function return will always have height zero. | |
| 73 if (cgen_->IsActualFunctionReturn(this)) { | |
| 74 current_frame->Forget(current_frame->height()); | |
| 75 } | |
| 76 current_frame->MakeMergable(); | 72 current_frame->MakeMergable(); |
| 77 expected_frame_ = current_frame; | 73 expected_frame_ = current_frame; |
| 78 ASSERT(cgen_->HasValidEntryRegisters()); | 74 ASSERT(cgen_->HasValidEntryRegisters()); |
| 79 cgen_->SetFrame(NULL); | 75 cgen_->SetFrame(NULL); |
| 80 } else { | 76 } else { |
| 81 // No code needs to be emitted to merge to the expected frame at the | 77 current_frame->MergeTo(expected_frame_); |
| 82 // actual function return. | |
| 83 if (!cgen_->IsActualFunctionReturn(this)) { | |
| 84 current_frame->MergeTo(expected_frame_); | |
| 85 } | |
| 86 ASSERT(cgen_->HasValidEntryRegisters()); | 78 ASSERT(cgen_->HasValidEntryRegisters()); |
| 87 cgen_->DeleteFrame(); | 79 cgen_->DeleteFrame(); |
| 88 } | 80 } |
| 89 | 81 |
| 90 __ jmp(&label_); | 82 __ jmp(&label_); |
| 91 // Postcondition: there is no current frame but there is an expected frame | 83 // Postcondition: there is no current frame but there is an expected frame |
| 92 // at the label. | 84 // at the label. |
| 93 } | 85 } |
| 94 | 86 |
| 95 | 87 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 107 // expected frame at the label. | 99 // expected frame at the label. |
| 108 ASSERT(cgen_ != NULL); | 100 ASSERT(cgen_ != NULL); |
| 109 ASSERT(masm_ != NULL); | 101 ASSERT(masm_ != NULL); |
| 110 | 102 |
| 111 VirtualFrame* current_frame = cgen_->frame(); | 103 VirtualFrame* current_frame = cgen_->frame(); |
| 112 ASSERT(current_frame != NULL); | 104 ASSERT(current_frame != NULL); |
| 113 ASSERT(cgen_->HasValidEntryRegisters()); | 105 ASSERT(cgen_->HasValidEntryRegisters()); |
| 114 | 106 |
| 115 if (expected_frame_ == NULL) { | 107 if (expected_frame_ == NULL) { |
| 116 expected_frame_ = new VirtualFrame(current_frame); | 108 expected_frame_ = new VirtualFrame(current_frame); |
| 117 // The frame at the actual function return will always have height zero. | |
| 118 if (cgen_->IsActualFunctionReturn(this)) { | |
| 119 expected_frame_->Forget(expected_frame_->height()); | |
| 120 } | |
| 121 // For a branch, the frame at the fall-through basic block (not labeled) | 109 // For a branch, the frame at the fall-through basic block (not labeled) |
| 122 // does not need to be mergable, but only the other (labeled) one. That | 110 // does not need to be mergable, but only the other (labeled) one. That |
| 123 // is achieved by reversing the condition and emitting the make mergable | 111 // is achieved by reversing the condition and emitting the make mergable |
| 124 // code as the actual fall-through block. This is necessary only when | 112 // code as the actual fall-through block. This is necessary only when |
| 125 // MakeMergable will generate code. | 113 // MakeMergable will generate code. |
| 126 if (expected_frame_->RequiresMergeCode()) { | 114 if (expected_frame_->RequiresMergeCode()) { |
| 127 Label original_fall_through; | 115 Label original_fall_through; |
| 128 __ j(NegateCondition(cc), &original_fall_through, NegateHint(hint)); | 116 __ j(NegateCondition(cc), &original_fall_through, NegateHint(hint)); |
| 129 expected_frame_->MakeMergable(); | 117 expected_frame_->MakeMergable(); |
| 130 __ jmp(&label_); | 118 __ jmp(&label_); |
| 131 __ bind(&original_fall_through); | 119 __ bind(&original_fall_through); |
| 132 } else { | 120 } else { |
| 133 expected_frame_->MakeMergable(); | 121 expected_frame_->MakeMergable(); |
| 134 ASSERT(cgen_->HasValidEntryRegisters()); | 122 ASSERT(cgen_->HasValidEntryRegisters()); |
| 135 __ j(cc, &label_, hint); | 123 __ j(cc, &label_, hint); |
| 136 } | 124 } |
| 137 } else { | 125 } else { |
| 138 // No code needs to be emitted to merge to the expected frame at the | 126 // We negate the condition and emit the code to merge to the expected |
| 139 // actual function return. | 127 // frame immediately. |
| 140 if (cgen_->IsActualFunctionReturn(this)) { | 128 // |
| 141 ASSERT(cgen_->HasValidEntryRegisters()); | 129 // TODO(): This should be replaced with a solution that emits the |
| 142 __ j(cc, &label_, hint); | 130 // merge code for forward CFG edges at the appropriate entry to the |
| 143 } else { | 131 // target block. |
| 144 // We negate the condition and emit the code to merge to the expected | 132 Label original_fall_through; |
| 145 // frame immediately. | 133 __ j(NegateCondition(cc), &original_fall_through, NegateHint(hint)); |
| 146 // | 134 VirtualFrame* working_frame = new VirtualFrame(current_frame); |
| 147 // TODO(): This should be replaced with a solution that emits the | 135 cgen_->SetFrame(working_frame); |
| 148 // merge code for forward CFG edges at the appropriate entry to the | 136 working_frame->MergeTo(expected_frame_); |
| 149 // target block. | 137 ASSERT(cgen_->HasValidEntryRegisters()); |
| 150 Label original_fall_through; | 138 __ jmp(&label_); |
| 151 __ j(NegateCondition(cc), &original_fall_through, NegateHint(hint)); | 139 cgen_->SetFrame(current_frame); |
| 152 VirtualFrame* working_frame = new VirtualFrame(current_frame); | 140 delete working_frame; |
| 153 cgen_->SetFrame(working_frame); | 141 __ bind(&original_fall_through); |
| 154 working_frame->MergeTo(expected_frame_); | |
| 155 ASSERT(cgen_->HasValidEntryRegisters()); | |
| 156 __ jmp(&label_); | |
| 157 cgen_->SetFrame(current_frame); | |
| 158 delete working_frame; | |
| 159 __ bind(&original_fall_through); | |
| 160 } | |
| 161 } | 142 } |
| 162 // Postcondition: there is both a current frame and an expected frame at | 143 // Postcondition: there is both a current frame and an expected frame at |
| 163 // the label and they match. | 144 // the label and they match. |
| 164 } | 145 } |
| 165 | 146 |
| 166 | 147 |
| 167 void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) { | 148 void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) { |
| 168 ASSERT(cgen_ != NULL); | 149 ASSERT(cgen_ != NULL); |
| 169 ASSERT(cgen_->has_valid_frame()); | 150 ASSERT(cgen_->has_valid_frame()); |
| 170 | 151 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 ASSERT(arg1->type() == arg1_type); | 189 ASSERT(arg1->type() == arg1_type); |
| 209 ASSERT(!arg1->is_register() || arg1->reg().is(arg1_reg)); | 190 ASSERT(!arg1->is_register() || arg1->reg().is(arg1_reg)); |
| 210 } | 191 } |
| 211 | 192 |
| 212 | 193 |
| 213 void JumpTarget::Call() { | 194 void JumpTarget::Call() { |
| 214 // Precondition: there is a current frame, and there is no expected frame | 195 // Precondition: there is a current frame, and there is no expected frame |
| 215 // at the label. | 196 // at the label. |
| 216 ASSERT(cgen_ != NULL); | 197 ASSERT(cgen_ != NULL); |
| 217 ASSERT(masm_ != NULL); | 198 ASSERT(masm_ != NULL); |
| 218 ASSERT(!cgen_->IsActualFunctionReturn(this)); | |
| 219 | 199 |
| 220 VirtualFrame* current_frame = cgen_->frame(); | 200 VirtualFrame* current_frame = cgen_->frame(); |
| 221 ASSERT(current_frame != NULL); | 201 ASSERT(current_frame != NULL); |
| 222 ASSERT(expected_frame_ == NULL); | 202 ASSERT(expected_frame_ == NULL); |
| 223 ASSERT(cgen_->HasValidEntryRegisters()); | 203 ASSERT(cgen_->HasValidEntryRegisters()); |
| 224 | 204 |
| 225 expected_frame_ = new VirtualFrame(current_frame); | 205 expected_frame_ = new VirtualFrame(current_frame); |
| 226 expected_frame_->MakeMergable(); | 206 expected_frame_->MakeMergable(); |
| 227 // Adjust the expected frame's height to account for the return address | 207 // Adjust the expected frame's height to account for the return address |
| 228 // pushed by the call instruction. | 208 // pushed by the call instruction. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 243 ASSERT(masm_ != NULL); | 223 ASSERT(masm_ != NULL); |
| 244 | 224 |
| 245 VirtualFrame* current_frame = cgen_->frame(); | 225 VirtualFrame* current_frame = cgen_->frame(); |
| 246 ASSERT(current_frame != NULL || expected_frame_ != NULL); | 226 ASSERT(current_frame != NULL || expected_frame_ != NULL); |
| 247 ASSERT(!label_.is_bound()); | 227 ASSERT(!label_.is_bound()); |
| 248 | 228 |
| 249 if (expected_frame_ == NULL) { | 229 if (expected_frame_ == NULL) { |
| 250 ASSERT(cgen_->HasValidEntryRegisters()); | 230 ASSERT(cgen_->HasValidEntryRegisters()); |
| 251 // When a label is bound the current frame becomes the expected frame at | 231 // When a label is bound the current frame becomes the expected frame at |
| 252 // the label. This requires the current frame to be mergable. | 232 // the label. This requires the current frame to be mergable. |
| 253 // The frame at the actual function return will always have height zero. | |
| 254 if (cgen_->IsActualFunctionReturn(this)) { | |
| 255 current_frame->Forget(current_frame->height()); | |
| 256 } | |
| 257 current_frame->MakeMergable(); | 233 current_frame->MakeMergable(); |
| 258 ASSERT(cgen_->HasValidEntryRegisters()); | 234 ASSERT(cgen_->HasValidEntryRegisters()); |
| 259 expected_frame_ = new VirtualFrame(current_frame); | 235 expected_frame_ = new VirtualFrame(current_frame); |
| 260 } else if (current_frame == NULL) { | 236 } else if (current_frame == NULL) { |
| 261 cgen_->SetFrame(new VirtualFrame(expected_frame_)); | 237 cgen_->SetFrame(new VirtualFrame(expected_frame_)); |
| 262 ASSERT(cgen_->HasValidEntryRegisters()); | 238 ASSERT(cgen_->HasValidEntryRegisters()); |
| 263 } else { | 239 } else { |
| 264 ASSERT(cgen_->HasValidEntryRegisters()); | 240 ASSERT(cgen_->HasValidEntryRegisters()); |
| 265 // No code needs to be emitted to merge to the expected frame at the | 241 current_frame->MergeTo(expected_frame_); |
| 266 // actual function return. | |
| 267 if (!cgen_->IsActualFunctionReturn(this)) { | |
| 268 current_frame->MergeTo(expected_frame_); | |
| 269 } | |
| 270 ASSERT(cgen_->HasValidEntryRegisters()); | 242 ASSERT(cgen_->HasValidEntryRegisters()); |
| 271 } | 243 } |
| 272 | 244 |
| 273 __ bind(&label_); | 245 __ bind(&label_); |
| 274 // Postcondition: there is both a current frame and an expected frame at | 246 // Postcondition: there is both a current frame and an expected frame at |
| 275 // the label and they match. The label is bound. | 247 // the label and they match. The label is bound. |
| 276 } | 248 } |
| 277 | 249 |
| 278 | 250 |
| 279 void JumpTarget::Bind(Result* arg) { | 251 void JumpTarget::Bind(Result* arg) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 | 346 |
| 375 #ifdef DEBUG | 347 #ifdef DEBUG |
| 376 is_shadowing_ = false; | 348 is_shadowing_ = false; |
| 377 #endif | 349 #endif |
| 378 } | 350 } |
| 379 | 351 |
| 380 #undef __ | 352 #undef __ |
| 381 | 353 |
| 382 | 354 |
| 383 } } // namespace v8::internal | 355 } } // namespace v8::internal |
| OLD | NEW |