OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 } | 467 } |
468 ASSERT(has_cc() || !force_cc); | 468 ASSERT(has_cc() || !force_cc); |
469 } | 469 } |
470 | 470 |
471 | 471 |
472 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { | 472 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { |
473 Label true_target; | 473 Label true_target; |
474 Label false_target; | 474 Label false_target; |
475 LoadCondition(x, typeof_state, &true_target, &false_target, false); | 475 LoadCondition(x, typeof_state, &true_target, &false_target, false); |
476 | 476 |
| 477 // Materialize boolean values on the stack frame if necessary. |
477 if (has_cc()) { | 478 if (has_cc()) { |
478 // convert cc_reg_ into a bool | 479 // The value we want is in the cc register. Since complicated |
479 | 480 // conditions can require more than one test, there may also be branches |
480 Label loaded, materialize_true; | 481 // to true_target and false_target. |
481 __ j(cc_reg_, &materialize_true); | 482 Label loaded; |
| 483 __ j(cc_reg_, &true_target); |
| 484 __ bind(&false_target); |
482 frame_->Push(Immediate(Factory::false_value())); | 485 frame_->Push(Immediate(Factory::false_value())); |
483 __ jmp(&loaded); | 486 __ jmp(&loaded); |
484 __ bind(&materialize_true); | 487 __ bind(&true_target); |
485 frame_->Push(Immediate(Factory::true_value())); | 488 frame_->Push(Immediate(Factory::true_value())); |
486 __ bind(&loaded); | 489 __ bind(&loaded); |
487 cc_reg_ = no_condition; | 490 cc_reg_ = no_condition; |
488 } | 491 } else { |
| 492 // Optimization of boolean-valued expressions whose value is statically |
| 493 // known may have generated an unconditional jump to either of the |
| 494 // targets (but not both) and failed to leave a value in either the cc |
| 495 // register or on top of the frame. |
| 496 ASSERT(!(true_target.is_linked() && false_target.is_linked())); |
489 | 497 |
490 if (true_target.is_linked() || false_target.is_linked()) { | |
491 // we have at least one condition value | |
492 // that has been "translated" into a branch, | |
493 // thus it needs to be loaded explicitly again | |
494 Label loaded; | |
495 __ jmp(&loaded); // don't lose current TOS | |
496 bool both = true_target.is_linked() && false_target.is_linked(); | |
497 // reincarnate "true", if necessary | |
498 if (true_target.is_linked()) { | 498 if (true_target.is_linked()) { |
499 __ bind(&true_target); | 499 __ bind(&true_target); |
500 frame_->Push(Immediate(Factory::true_value())); | 500 frame_->Push(Immediate(Factory::true_value())); |
501 } | 501 } |
502 // if both "true" and "false" need to be reincarnated, | 502 |
503 // jump across code for "false" | |
504 if (both) | |
505 __ jmp(&loaded); | |
506 // reincarnate "false", if necessary | |
507 if (false_target.is_linked()) { | 503 if (false_target.is_linked()) { |
508 __ bind(&false_target); | 504 __ bind(&false_target); |
509 frame_->Push(Immediate(Factory::false_value())); | 505 frame_->Push(Immediate(Factory::false_value())); |
510 } | 506 } |
511 // everything is loaded at this point | |
512 __ bind(&loaded); | |
513 } | 507 } |
514 ASSERT(!has_cc()); | |
515 } | 508 } |
516 | 509 |
517 | 510 |
518 void CodeGenerator::LoadGlobal() { | 511 void CodeGenerator::LoadGlobal() { |
519 frame_->Push(GlobalObject()); | 512 frame_->Push(GlobalObject()); |
520 } | 513 } |
521 | 514 |
522 | 515 |
523 void CodeGenerator::LoadGlobalReceiver(Register scratch) { | 516 void CodeGenerator::LoadGlobalReceiver(Register scratch) { |
524 __ mov(scratch, GlobalObject()); | 517 __ mov(scratch, GlobalObject()); |
(...skipping 4609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5134 | 5127 |
5135 // Slow-case: Go through the JavaScript implementation. | 5128 // Slow-case: Go through the JavaScript implementation. |
5136 __ bind(&slow); | 5129 __ bind(&slow); |
5137 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5130 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
5138 } | 5131 } |
5139 | 5132 |
5140 | 5133 |
5141 #undef __ | 5134 #undef __ |
5142 | 5135 |
5143 } } // namespace v8::internal | 5136 } } // namespace v8::internal |
OLD | NEW |