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

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

Issue 113458: First round of size reduction for JumpTargets. Reduce their size by... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 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 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 21 matching lines...) Expand all
32 #include "register-allocator-inl.h" 32 #include "register-allocator-inl.h"
33 33
34 namespace v8 { namespace internal { 34 namespace v8 { namespace internal {
35 35
36 // ------------------------------------------------------------------------- 36 // -------------------------------------------------------------------------
37 // JumpTarget implementation. 37 // JumpTarget implementation.
38 38
39 bool JumpTarget::compiling_deferred_code_ = false; 39 bool JumpTarget::compiling_deferred_code_ = false;
40 40
41 41
42 JumpTarget::JumpTarget(CodeGenerator* cgen, Directionality direction)
43 : cgen_(cgen),
44 direction_(direction),
45 reaching_frames_(0),
46 merge_labels_(0),
47 entry_frame_(NULL) {
48 ASSERT(cgen != NULL);
49 masm_ = cgen->masm();
50 }
51
52
53 JumpTarget::JumpTarget()
54 : cgen_(NULL),
55 masm_(NULL),
56 direction_(FORWARD_ONLY),
57 reaching_frames_(0),
58 merge_labels_(0),
59 entry_frame_(NULL) {
60 }
61
62
63 void JumpTarget::Initialize(CodeGenerator* cgen, Directionality direction) {
64 ASSERT(cgen != NULL);
65 ASSERT(cgen_ == NULL);
66 cgen_ = cgen;
67 masm_ = cgen->masm();
68 direction_ = direction;
69 }
70
71
72 void JumpTarget::Unuse() { 42 void JumpTarget::Unuse() {
73 reaching_frames_.Clear(); 43 reaching_frames_.Clear();
74 merge_labels_.Clear(); 44 merge_labels_.Clear();
75 entry_frame_ = NULL; 45 entry_frame_ = NULL;
76 entry_label_.Unuse(); 46 entry_label_.Unuse();
77 } 47 }
78 48
79 49
80 void JumpTarget::ComputeEntryFrame(int mergable_elements) { 50 void JumpTarget::ComputeEntryFrame(int mergable_elements) {
81 // Given: a collection of frames reaching by forward CFG edges and 51 // Given: a collection of frames reaching by forward CFG edges and
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 114
145 element = element->Combine(&reaching_frames_[j]->elements_[i]); 115 element = element->Combine(&reaching_frames_[j]->elements_[i]);
146 } 116 }
147 elements[i] = element; 117 elements[i] = element;
148 } 118 }
149 } 119 }
150 120
151 // Build the new frame. A freshly allocated frame has memory elements 121 // Build the new frame. A freshly allocated frame has memory elements
152 // for the parameters and some platform-dependent elements (e.g., 122 // for the parameters and some platform-dependent elements (e.g.,
153 // return address). Replace those first. 123 // return address). Replace those first.
154 entry_frame_ = new VirtualFrame(cgen_); 124 entry_frame_ = new VirtualFrame(cgen());
155 int index = 0; 125 int index = 0;
156 for (; index < entry_frame_->elements_.length(); index++) { 126 for (; index < entry_frame_->elements_.length(); index++) {
157 FrameElement* target = elements[index]; 127 FrameElement* target = elements[index];
158 // If the element is determined, set it now. Count registers. Mark 128 // If the element is determined, set it now. Count registers. Mark
159 // elements as copied exactly when they have a copy. Undetermined 129 // elements as copied exactly when they have a copy. Undetermined
160 // elements are initially recorded as if in memory. 130 // elements are initially recorded as if in memory.
161 if (target != NULL) { 131 if (target != NULL) {
162 entry_frame_->elements_[index] = *target; 132 entry_frame_->elements_[index] = *target;
163 InitializeEntryElement(index, target); 133 InitializeEntryElement(index, target);
164 } 134 }
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 entry_frame_->stack_pointer_ = stack_pointer; 229 entry_frame_->stack_pointer_ = stack_pointer;
260 } 230 }
261 231
262 232
263 void JumpTarget::Jump() { 233 void JumpTarget::Jump() {
264 DoJump(); 234 DoJump();
265 } 235 }
266 236
267 237
268 void JumpTarget::Jump(Result* arg) { 238 void JumpTarget::Jump(Result* arg) {
269 ASSERT(cgen_ != NULL); 239 ASSERT(cgen()->has_valid_frame());
270 ASSERT(cgen_->has_valid_frame());
271 240
272 cgen_->frame()->Push(arg); 241 cgen()->frame()->Push(arg);
273 DoJump(); 242 DoJump();
274 } 243 }
275 244
276 245
277 void JumpTarget::Jump(Result* arg0, Result* arg1) { 246 void JumpTarget::Jump(Result* arg0, Result* arg1) {
278 ASSERT(cgen_ != NULL); 247 ASSERT(cgen()->has_valid_frame());
279 ASSERT(cgen_->has_valid_frame());
280 248
281 cgen_->frame()->Push(arg0); 249 cgen()->frame()->Push(arg0);
282 cgen_->frame()->Push(arg1); 250 cgen()->frame()->Push(arg1);
283 DoJump(); 251 DoJump();
284 } 252 }
285 253
286 254
287 void JumpTarget::Jump(Result* arg0, Result* arg1, Result* arg2) { 255 void JumpTarget::Jump(Result* arg0, Result* arg1, Result* arg2) {
288 ASSERT(cgen_ != NULL); 256 ASSERT(cgen()->has_valid_frame());
289 ASSERT(cgen_->has_valid_frame());
290 257
291 cgen_->frame()->Push(arg0); 258 cgen()->frame()->Push(arg0);
292 cgen_->frame()->Push(arg1); 259 cgen()->frame()->Push(arg1);
293 cgen_->frame()->Push(arg2); 260 cgen()->frame()->Push(arg2);
294 DoJump(); 261 DoJump();
295 } 262 }
296 263
297 264
298 void JumpTarget::Branch(Condition cc, Hint hint) { 265 void JumpTarget::Branch(Condition cc, Hint hint) {
299 DoBranch(cc, hint); 266 DoBranch(cc, hint);
300 } 267 }
301 268
302 269
303 #ifdef DEBUG 270 #ifdef DEBUG
304 #define DECLARE_ARGCHECK_VARS(name) \ 271 #define DECLARE_ARGCHECK_VARS(name) \
305 Result::Type name##_type = name->type(); \ 272 Result::Type name##_type = name->type(); \
306 Register name##_reg = name->is_register() ? name->reg() : no_reg 273 Register name##_reg = name->is_register() ? name->reg() : no_reg
307 274
308 #define ASSERT_ARGCHECK(name) \ 275 #define ASSERT_ARGCHECK(name) \
309 ASSERT(name->type() == name##_type); \ 276 ASSERT(name->type() == name##_type); \
310 ASSERT(!name->is_register() || name->reg().is(name##_reg)) 277 ASSERT(!name->is_register() || name->reg().is(name##_reg))
311 278
312 #else 279 #else
313 #define DECLARE_ARGCHECK_VARS(name) do {} while (false) 280 #define DECLARE_ARGCHECK_VARS(name) do {} while (false)
314 281
315 #define ASSERT_ARGCHECK(name) do {} while (false) 282 #define ASSERT_ARGCHECK(name) do {} while (false)
316 #endif 283 #endif
317 284
318 void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) { 285 void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) {
319 ASSERT(cgen_ != NULL); 286 ASSERT(cgen()->has_valid_frame());
320 ASSERT(cgen_->has_valid_frame());
321 287
322 // We want to check that non-frame registers at the call site stay in 288 // We want to check that non-frame registers at the call site stay in
323 // the same registers on the fall-through branch. 289 // the same registers on the fall-through branch.
324 DECLARE_ARGCHECK_VARS(arg); 290 DECLARE_ARGCHECK_VARS(arg);
325 291
326 cgen_->frame()->Push(arg); 292 cgen()->frame()->Push(arg);
327 DoBranch(cc, hint); 293 DoBranch(cc, hint);
328 *arg = cgen_->frame()->Pop(); 294 *arg = cgen()->frame()->Pop();
329 295
330 ASSERT_ARGCHECK(arg); 296 ASSERT_ARGCHECK(arg);
331 } 297 }
332 298
333 299
334 void JumpTarget::Branch(Condition cc, Result* arg0, Result* arg1, Hint hint) { 300 void JumpTarget::Branch(Condition cc, Result* arg0, Result* arg1, Hint hint) {
335 ASSERT(cgen_ != NULL); 301 ASSERT(cgen()->frame() != NULL);
336 ASSERT(cgen_->frame() != NULL);
337 302
338 // We want to check that non-frame registers at the call site stay in 303 // We want to check that non-frame registers at the call site stay in
339 // the same registers on the fall-through branch. 304 // the same registers on the fall-through branch.
340 DECLARE_ARGCHECK_VARS(arg0); 305 DECLARE_ARGCHECK_VARS(arg0);
341 DECLARE_ARGCHECK_VARS(arg1); 306 DECLARE_ARGCHECK_VARS(arg1);
342 307
343 cgen_->frame()->Push(arg0); 308 cgen()->frame()->Push(arg0);
344 cgen_->frame()->Push(arg1); 309 cgen()->frame()->Push(arg1);
345 DoBranch(cc, hint); 310 DoBranch(cc, hint);
346 *arg1 = cgen_->frame()->Pop(); 311 *arg1 = cgen()->frame()->Pop();
347 *arg0 = cgen_->frame()->Pop(); 312 *arg0 = cgen()->frame()->Pop();
348 313
349 ASSERT_ARGCHECK(arg0); 314 ASSERT_ARGCHECK(arg0);
350 ASSERT_ARGCHECK(arg1); 315 ASSERT_ARGCHECK(arg1);
351 } 316 }
352 317
353 318
354 void JumpTarget::Branch(Condition cc, 319 void JumpTarget::Branch(Condition cc,
355 Result* arg0, 320 Result* arg0,
356 Result* arg1, 321 Result* arg1,
357 Result* arg2, 322 Result* arg2,
358 Hint hint) { 323 Hint hint) {
359 ASSERT(cgen_ != NULL); 324 ASSERT(cgen()->frame() != NULL);
360 ASSERT(cgen_->frame() != NULL);
361 325
362 // We want to check that non-frame registers at the call site stay in 326 // We want to check that non-frame registers at the call site stay in
363 // the same registers on the fall-through branch. 327 // the same registers on the fall-through branch.
364 DECLARE_ARGCHECK_VARS(arg0); 328 DECLARE_ARGCHECK_VARS(arg0);
365 DECLARE_ARGCHECK_VARS(arg1); 329 DECLARE_ARGCHECK_VARS(arg1);
366 DECLARE_ARGCHECK_VARS(arg2); 330 DECLARE_ARGCHECK_VARS(arg2);
367 331
368 cgen_->frame()->Push(arg0); 332 cgen()->frame()->Push(arg0);
369 cgen_->frame()->Push(arg1); 333 cgen()->frame()->Push(arg1);
370 cgen_->frame()->Push(arg2); 334 cgen()->frame()->Push(arg2);
371 DoBranch(cc, hint); 335 DoBranch(cc, hint);
372 *arg2 = cgen_->frame()->Pop(); 336 *arg2 = cgen()->frame()->Pop();
373 *arg1 = cgen_->frame()->Pop(); 337 *arg1 = cgen()->frame()->Pop();
374 *arg0 = cgen_->frame()->Pop(); 338 *arg0 = cgen()->frame()->Pop();
375 339
376 ASSERT_ARGCHECK(arg0); 340 ASSERT_ARGCHECK(arg0);
377 ASSERT_ARGCHECK(arg1); 341 ASSERT_ARGCHECK(arg1);
378 ASSERT_ARGCHECK(arg2); 342 ASSERT_ARGCHECK(arg2);
379 } 343 }
380 344
381 345
382 void JumpTarget::Branch(Condition cc, 346 void JumpTarget::Branch(Condition cc,
383 Result* arg0, 347 Result* arg0,
384 Result* arg1, 348 Result* arg1,
385 Result* arg2, 349 Result* arg2,
386 Result* arg3, 350 Result* arg3,
387 Hint hint) { 351 Hint hint) {
388 ASSERT(cgen_ != NULL); 352 ASSERT(cgen()->frame() != NULL);
389 ASSERT(cgen_->frame() != NULL);
390 353
391 // We want to check that non-frame registers at the call site stay in 354 // We want to check that non-frame registers at the call site stay in
392 // the same registers on the fall-through branch. 355 // the same registers on the fall-through branch.
393 DECLARE_ARGCHECK_VARS(arg0); 356 DECLARE_ARGCHECK_VARS(arg0);
394 DECLARE_ARGCHECK_VARS(arg1); 357 DECLARE_ARGCHECK_VARS(arg1);
395 DECLARE_ARGCHECK_VARS(arg2); 358 DECLARE_ARGCHECK_VARS(arg2);
396 DECLARE_ARGCHECK_VARS(arg3); 359 DECLARE_ARGCHECK_VARS(arg3);
397 360
398 cgen_->frame()->Push(arg0); 361 cgen()->frame()->Push(arg0);
399 cgen_->frame()->Push(arg1); 362 cgen()->frame()->Push(arg1);
400 cgen_->frame()->Push(arg2); 363 cgen()->frame()->Push(arg2);
401 cgen_->frame()->Push(arg3); 364 cgen()->frame()->Push(arg3);
402 DoBranch(cc, hint); 365 DoBranch(cc, hint);
403 *arg3 = cgen_->frame()->Pop(); 366 *arg3 = cgen()->frame()->Pop();
404 *arg2 = cgen_->frame()->Pop(); 367 *arg2 = cgen()->frame()->Pop();
405 *arg1 = cgen_->frame()->Pop(); 368 *arg1 = cgen()->frame()->Pop();
406 *arg0 = cgen_->frame()->Pop(); 369 *arg0 = cgen()->frame()->Pop();
407 370
408 ASSERT_ARGCHECK(arg0); 371 ASSERT_ARGCHECK(arg0);
409 ASSERT_ARGCHECK(arg1); 372 ASSERT_ARGCHECK(arg1);
410 ASSERT_ARGCHECK(arg2); 373 ASSERT_ARGCHECK(arg2);
411 ASSERT_ARGCHECK(arg3); 374 ASSERT_ARGCHECK(arg3);
412 } 375 }
413 376
414 377
415 void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) { 378 void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) {
416 ASSERT(cgen_ != NULL); 379 ASSERT(cgen()->has_valid_frame());
417 ASSERT(cgen_->has_valid_frame());
418 380
419 int count = cgen_->frame()->height() - expected_height_; 381 int count = cgen()->frame()->height() - expected_height_;
420 if (count > 0) { 382 if (count > 0) {
421 // We negate and branch here rather than using DoBranch's negate 383 // We negate and branch here rather than using DoBranch's negate
422 // and branch. This gives us a hook to remove statement state 384 // and branch. This gives us a hook to remove statement state
423 // from the frame. 385 // from the frame.
424 JumpTarget fall_through(cgen_); 386 JumpTarget fall_through;
425 // Branch to fall through will not negate, because it is a 387 // Branch to fall through will not negate, because it is a
426 // forward-only target. 388 // forward-only target.
427 fall_through.Branch(NegateCondition(cc), NegateHint(hint)); 389 fall_through.Branch(NegateCondition(cc), NegateHint(hint));
428 Jump(arg); // May emit merge code here. 390 Jump(arg); // May emit merge code here.
429 fall_through.Bind(); 391 fall_through.Bind();
430 } else { 392 } else {
431 DECLARE_ARGCHECK_VARS(arg); 393 DECLARE_ARGCHECK_VARS(arg);
432 cgen_->frame()->Push(arg); 394 cgen()->frame()->Push(arg);
433 DoBranch(cc, hint); 395 DoBranch(cc, hint);
434 *arg = cgen_->frame()->Pop(); 396 *arg = cgen()->frame()->Pop();
435 ASSERT_ARGCHECK(arg); 397 ASSERT_ARGCHECK(arg);
436 } 398 }
437 } 399 }
438 400
439 #undef DECLARE_ARGCHECK_VARS 401 #undef DECLARE_ARGCHECK_VARS
440 #undef ASSERT_ARGCHECK 402 #undef ASSERT_ARGCHECK
441 403
442 404
443 void JumpTarget::Bind(int mergable_elements) { 405 void JumpTarget::Bind(int mergable_elements) {
444 DoBind(mergable_elements); 406 DoBind(mergable_elements);
445 } 407 }
446 408
447 409
448 void JumpTarget::Bind(Result* arg, int mergable_elements) { 410 void JumpTarget::Bind(Result* arg, int mergable_elements) {
449 ASSERT(cgen_ != NULL); 411 if (cgen()->has_valid_frame()) {
450 412 cgen()->frame()->Push(arg);
451 if (cgen_->has_valid_frame()) {
452 cgen_->frame()->Push(arg);
453 } 413 }
454 DoBind(mergable_elements); 414 DoBind(mergable_elements);
455 *arg = cgen_->frame()->Pop(); 415 *arg = cgen()->frame()->Pop();
456 } 416 }
457 417
458 418
459 void JumpTarget::Bind(Result* arg0, Result* arg1, int mergable_elements) { 419 void JumpTarget::Bind(Result* arg0, Result* arg1, int mergable_elements) {
460 ASSERT(cgen_ != NULL); 420 if (cgen()->has_valid_frame()) {
461 421 cgen()->frame()->Push(arg0);
462 if (cgen_->has_valid_frame()) { 422 cgen()->frame()->Push(arg1);
463 cgen_->frame()->Push(arg0);
464 cgen_->frame()->Push(arg1);
465 } 423 }
466 DoBind(mergable_elements); 424 DoBind(mergable_elements);
467 *arg1 = cgen_->frame()->Pop(); 425 *arg1 = cgen()->frame()->Pop();
468 *arg0 = cgen_->frame()->Pop(); 426 *arg0 = cgen()->frame()->Pop();
469 } 427 }
470 428
471 429
472 void JumpTarget::Bind(Result* arg0, 430 void JumpTarget::Bind(Result* arg0,
473 Result* arg1, 431 Result* arg1,
474 Result* arg2, 432 Result* arg2,
475 int mergable_elements) { 433 int mergable_elements) {
476 ASSERT(cgen_ != NULL); 434 if (cgen()->has_valid_frame()) {
477 435 cgen()->frame()->Push(arg0);
478 if (cgen_->has_valid_frame()) { 436 cgen()->frame()->Push(arg1);
479 cgen_->frame()->Push(arg0); 437 cgen()->frame()->Push(arg2);
480 cgen_->frame()->Push(arg1);
481 cgen_->frame()->Push(arg2);
482 } 438 }
483 DoBind(mergable_elements); 439 DoBind(mergable_elements);
484 *arg2 = cgen_->frame()->Pop(); 440 *arg2 = cgen()->frame()->Pop();
485 *arg1 = cgen_->frame()->Pop(); 441 *arg1 = cgen()->frame()->Pop();
486 *arg0 = cgen_->frame()->Pop(); 442 *arg0 = cgen()->frame()->Pop();
487 } 443 }
488 444
489 445
490 void JumpTarget::Bind(Result* arg0, 446 void JumpTarget::Bind(Result* arg0,
491 Result* arg1, 447 Result* arg1,
492 Result* arg2, 448 Result* arg2,
493 Result* arg3, 449 Result* arg3,
494 int mergable_elements) { 450 int mergable_elements) {
495 ASSERT(cgen_ != NULL); 451 if (cgen()->has_valid_frame()) {
496 452 cgen()->frame()->Push(arg0);
497 if (cgen_->has_valid_frame()) { 453 cgen()->frame()->Push(arg1);
498 cgen_->frame()->Push(arg0); 454 cgen()->frame()->Push(arg2);
499 cgen_->frame()->Push(arg1); 455 cgen()->frame()->Push(arg3);
500 cgen_->frame()->Push(arg2);
501 cgen_->frame()->Push(arg3);
502 } 456 }
503 DoBind(mergable_elements); 457 DoBind(mergable_elements);
504 *arg3 = cgen_->frame()->Pop(); 458 *arg3 = cgen()->frame()->Pop();
505 *arg2 = cgen_->frame()->Pop(); 459 *arg2 = cgen()->frame()->Pop();
506 *arg1 = cgen_->frame()->Pop(); 460 *arg1 = cgen()->frame()->Pop();
507 *arg0 = cgen_->frame()->Pop(); 461 *arg0 = cgen()->frame()->Pop();
508 } 462 }
509 463
510 464
511 void JumpTarget::AddReachingFrame(VirtualFrame* frame) { 465 void JumpTarget::AddReachingFrame(VirtualFrame* frame) {
512 ASSERT(reaching_frames_.length() == merge_labels_.length()); 466 ASSERT(reaching_frames_.length() == merge_labels_.length());
513 ASSERT(entry_frame_ == NULL); 467 ASSERT(entry_frame_ == NULL);
514 Label fresh; 468 Label fresh;
515 merge_labels_.Add(fresh); 469 merge_labels_.Add(fresh);
516 reaching_frames_.Add(frame); 470 reaching_frames_.Add(frame);
517 } 471 }
518 472
519 473
520 // ------------------------------------------------------------------------- 474 // -------------------------------------------------------------------------
521 // BreakTarget implementation. 475 // BreakTarget implementation.
522 476
523 void BreakTarget::Initialize(CodeGenerator* cgen, Directionality direction) { 477 void BreakTarget::set_direction(Directionality direction) {
524 JumpTarget::Initialize(cgen, direction); 478 JumpTarget::set_direction(direction);
525 ASSERT(cgen_->has_valid_frame()); 479 ASSERT(cgen()->has_valid_frame());
526 expected_height_ = cgen_->frame()->height(); 480 expected_height_ = cgen()->frame()->height();
527 } 481 }
528 482
529 483
530 void BreakTarget::CopyTo(BreakTarget* destination) { 484 void BreakTarget::CopyTo(BreakTarget* destination) {
531 ASSERT(destination != NULL); 485 ASSERT(destination != NULL);
532 destination->cgen_ = cgen_;
533 destination->masm_ = masm_;
534 destination->direction_ = direction_; 486 destination->direction_ = direction_;
535 destination->reaching_frames_.Clear(); 487 destination->reaching_frames_.Clear();
536 destination->merge_labels_.Clear(); 488 destination->merge_labels_.Clear();
537 ASSERT(reaching_frames_.length() == merge_labels_.length()); 489 ASSERT(reaching_frames_.length() == merge_labels_.length());
538 for (int i = 0; i < reaching_frames_.length(); i++) { 490 for (int i = 0; i < reaching_frames_.length(); i++) {
539 destination->reaching_frames_.Add(reaching_frames_[i]); 491 destination->reaching_frames_.Add(reaching_frames_[i]);
540 destination->merge_labels_.Add(merge_labels_[i]); 492 destination->merge_labels_.Add(merge_labels_[i]);
541 } 493 }
542 destination->entry_frame_ = entry_frame_; 494 destination->entry_frame_ = entry_frame_;
543 destination->entry_label_ = entry_label_; 495 destination->entry_label_ = entry_label_;
544 destination->expected_height_ = expected_height_; 496 destination->expected_height_ = expected_height_;
545 } 497 }
546 498
547 499
548 void BreakTarget::Jump() { 500 void BreakTarget::Jump() {
549 ASSERT(cgen_ != NULL); 501 ASSERT(cgen()->has_valid_frame());
550 ASSERT(cgen_->has_valid_frame());
551 502
552 // Drop leftover statement state from the frame before merging. 503 // Drop leftover statement state from the frame before merging.
553 cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); 504 cgen()->frame()->ForgetElements(cgen()->frame()->height() - expected_height_);
554 DoJump(); 505 DoJump();
555 } 506 }
556 507
557 508
558 void BreakTarget::Jump(Result* arg) { 509 void BreakTarget::Jump(Result* arg) {
559 ASSERT(cgen_ != NULL); 510 ASSERT(cgen()->has_valid_frame());
560 ASSERT(cgen_->has_valid_frame());
561 511
562 // Drop leftover statement state from the frame before merging. 512 // Drop leftover statement state from the frame before merging.
563 cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); 513 cgen()->frame()->ForgetElements(cgen()->frame()->height() - expected_height_);
564 cgen_->frame()->Push(arg); 514 cgen()->frame()->Push(arg);
565 DoJump(); 515 DoJump();
566 } 516 }
567 517
568 518
569 void BreakTarget::Branch(Condition cc, Hint hint) { 519 void BreakTarget::Branch(Condition cc, Hint hint) {
570 ASSERT(cgen_ != NULL); 520 ASSERT(cgen()->has_valid_frame());
571 ASSERT(cgen_->has_valid_frame());
572 521
573 int count = cgen_->frame()->height() - expected_height_; 522 int count = cgen()->frame()->height() - expected_height_;
574 if (count > 0) { 523 if (count > 0) {
575 // We negate and branch here rather than using DoBranch's negate 524 // We negate and branch here rather than using DoBranch's negate
576 // and branch. This gives us a hook to remove statement state 525 // and branch. This gives us a hook to remove statement state
577 // from the frame. 526 // from the frame.
578 JumpTarget fall_through(cgen_); 527 JumpTarget fall_through;
579 // Branch to fall through will not negate, because it is a 528 // Branch to fall through will not negate, because it is a
580 // forward-only target. 529 // forward-only target.
581 fall_through.Branch(NegateCondition(cc), NegateHint(hint)); 530 fall_through.Branch(NegateCondition(cc), NegateHint(hint));
582 Jump(); // May emit merge code here. 531 Jump(); // May emit merge code here.
583 fall_through.Bind(); 532 fall_through.Bind();
584 } else { 533 } else {
585 DoBranch(cc, hint); 534 DoBranch(cc, hint);
586 } 535 }
587 } 536 }
588 537
589 538
590 void BreakTarget::Bind(int mergable_elements) { 539 void BreakTarget::Bind(int mergable_elements) {
591 #ifdef DEBUG 540 #ifdef DEBUG
592 ASSERT(cgen_ != NULL);
593 // All the forward-reaching frames should have been adjusted at the 541 // All the forward-reaching frames should have been adjusted at the
594 // jumps to this target. 542 // jumps to this target.
595 for (int i = 0; i < reaching_frames_.length(); i++) { 543 for (int i = 0; i < reaching_frames_.length(); i++) {
596 ASSERT(reaching_frames_[i] == NULL || 544 ASSERT(reaching_frames_[i] == NULL ||
597 reaching_frames_[i]->height() == expected_height_); 545 reaching_frames_[i]->height() == expected_height_);
598 } 546 }
599 #endif 547 #endif
600 // Drop leftover statement state from the frame before merging, even 548 // Drop leftover statement state from the frame before merging, even
601 // on the fall through. This is so we can bind the return target 549 // on the fall through. This is so we can bind the return target
602 // with state on the frame. 550 // with state on the frame.
603 if (cgen_->has_valid_frame()) { 551 if (cgen()->has_valid_frame()) {
604 cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); 552 int count = cgen()->frame()->height() - expected_height_;
553 cgen()->frame()->ForgetElements(count);
605 } 554 }
606 DoBind(mergable_elements); 555 DoBind(mergable_elements);
607 } 556 }
608 557
609 558
610 void BreakTarget::Bind(Result* arg, int mergable_elements) { 559 void BreakTarget::Bind(Result* arg, int mergable_elements) {
611 #ifdef DEBUG 560 #ifdef DEBUG
612 ASSERT(cgen_ != NULL);
613 // All the forward-reaching frames should have been adjusted at the 561 // All the forward-reaching frames should have been adjusted at the
614 // jumps to this target. 562 // jumps to this target.
615 for (int i = 0; i < reaching_frames_.length(); i++) { 563 for (int i = 0; i < reaching_frames_.length(); i++) {
616 ASSERT(reaching_frames_[i] == NULL || 564 ASSERT(reaching_frames_[i] == NULL ||
617 reaching_frames_[i]->height() == expected_height_ + 1); 565 reaching_frames_[i]->height() == expected_height_ + 1);
618 } 566 }
619 #endif 567 #endif
620 // Drop leftover statement state from the frame before merging, even 568 // Drop leftover statement state from the frame before merging, even
621 // on the fall through. This is so we can bind the return target 569 // on the fall through. This is so we can bind the return target
622 // with state on the frame. 570 // with state on the frame.
623 if (cgen_->has_valid_frame()) { 571 if (cgen()->has_valid_frame()) {
624 cgen_->frame()->ForgetElements(cgen_->frame()->height() - expected_height_); 572 int count = cgen()->frame()->height() - expected_height_;
625 cgen_->frame()->Push(arg); 573 cgen()->frame()->ForgetElements(count);
574 cgen()->frame()->Push(arg);
626 } 575 }
627 DoBind(mergable_elements); 576 DoBind(mergable_elements);
628 *arg = cgen_->frame()->Pop(); 577 *arg = cgen()->frame()->Pop();
629 } 578 }
630 579
631 580
632 // ------------------------------------------------------------------------- 581 // -------------------------------------------------------------------------
633 // ShadowTarget implementation. 582 // ShadowTarget implementation.
634 583
635 ShadowTarget::ShadowTarget(BreakTarget* shadowed) { 584 ShadowTarget::ShadowTarget(BreakTarget* shadowed) {
636 ASSERT(shadowed != NULL); 585 ASSERT(shadowed != NULL);
637 other_target_ = shadowed; 586 other_target_ = shadowed;
638 587
639 #ifdef DEBUG 588 #ifdef DEBUG
640 is_shadowing_ = true; 589 is_shadowing_ = true;
641 #endif 590 #endif
642 // While shadowing this shadow target saves the state of the original. 591 // While shadowing this shadow target saves the state of the original.
643 shadowed->CopyTo(this); 592 shadowed->CopyTo(this);
644 593
645 // The original's state is reset. 594 // The original's state is reset.
646 shadowed->Unuse(); 595 shadowed->Unuse();
647 ASSERT(cgen_ != NULL); 596 ASSERT(cgen()->has_valid_frame());
648 ASSERT(cgen_->has_valid_frame()); 597 shadowed->set_expected_height(cgen()->frame()->height());
649 shadowed->set_expected_height(cgen_->frame()->height());
650
651 // Setting the code generator to null prevents the shadow target from
652 // being used until shadowing stops.
653 cgen_ = NULL;
654 masm_ = NULL;
655 } 598 }
656 599
657 600
658 void ShadowTarget::StopShadowing() { 601 void ShadowTarget::StopShadowing() {
659 ASSERT(is_shadowing_); 602 ASSERT(is_shadowing_);
660 603
661 // This target does not have a valid code generator yet.
662 cgen_ = other_target_->code_generator();
663 ASSERT(cgen_ != NULL);
664 masm_ = cgen_->masm();
665
666 // The states of this target, which was shadowed, and the original 604 // The states of this target, which was shadowed, and the original
667 // target, which was shadowing, are swapped. 605 // target, which was shadowing, are swapped.
668 BreakTarget temp; 606 BreakTarget temp;
669 other_target_->CopyTo(&temp); 607 other_target_->CopyTo(&temp);
670 CopyTo(other_target_); 608 CopyTo(other_target_);
671 temp.CopyTo(this); 609 temp.CopyTo(this);
672 temp.Unuse(); 610 temp.Unuse();
673 611
674 #ifdef DEBUG 612 #ifdef DEBUG
675 is_shadowing_ = false; 613 is_shadowing_ = false;
676 #endif 614 #endif
677 } 615 }
678 616
679 617
680 } } // namespace v8::internal 618 } } // namespace v8::internal
OLDNEW
« src/jump-target.h ('K') | « src/jump-target.h ('k') | src/jump-target-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698