OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 return MemOperand(fp, -(index + 3) * kPointerSize + kPointerSize); | 457 return MemOperand(fp, -(index + 3) * kPointerSize + kPointerSize); |
458 } else { | 458 } else { |
459 // Incoming parameter. Skip the return address and the first word of | 459 // Incoming parameter. Skip the return address and the first word of |
460 // the double. | 460 // the double. |
461 return MemOperand(fp, -(index - 1) * kPointerSize + kPointerSize); | 461 return MemOperand(fp, -(index - 1) * kPointerSize + kPointerSize); |
462 } | 462 } |
463 } | 463 } |
464 | 464 |
465 | 465 |
466 void LCodeGen::WriteTranslation(LEnvironment* environment, | 466 void LCodeGen::WriteTranslation(LEnvironment* environment, |
467 Translation* translation) { | 467 Translation* translation, |
| 468 int* arguments_index, |
| 469 int* arguments_count) { |
468 if (environment == NULL) return; | 470 if (environment == NULL) return; |
469 | 471 |
470 // The translation includes one command per value in the environment. | 472 // The translation includes one command per value in the environment. |
471 int translation_size = environment->values()->length(); | 473 int translation_size = environment->values()->length(); |
472 // The output frame height does not include the parameters. | 474 // The output frame height does not include the parameters. |
473 int height = translation_size - environment->parameter_count(); | 475 int height = translation_size - environment->parameter_count(); |
474 | 476 |
475 WriteTranslation(environment->outer(), translation); | 477 // Function parameters are arguments to the outermost environment. The |
| 478 // arguments index points to the first element of a sequence of tagged |
| 479 // values on the stack that represent the arguments. This needs to be |
| 480 // kept in sync with the LArgumentsElements implementation. |
| 481 *arguments_index = -environment->parameter_count(); |
| 482 *arguments_count = environment->parameter_count(); |
| 483 |
| 484 WriteTranslation(environment->outer(), |
| 485 translation, |
| 486 arguments_index, |
| 487 arguments_count); |
476 int closure_id = *info()->closure() != *environment->closure() | 488 int closure_id = *info()->closure() != *environment->closure() |
477 ? DefineDeoptimizationLiteral(environment->closure()) | 489 ? DefineDeoptimizationLiteral(environment->closure()) |
478 : Translation::kSelfLiteralId; | 490 : Translation::kSelfLiteralId; |
479 | 491 |
480 switch (environment->frame_type()) { | 492 switch (environment->frame_type()) { |
481 case JS_FUNCTION: | 493 case JS_FUNCTION: |
482 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 494 translation->BeginJSFrame(environment->ast_id(), closure_id, height); |
483 break; | 495 break; |
484 case JS_CONSTRUCT: | 496 case JS_CONSTRUCT: |
485 translation->BeginConstructStubFrame(closure_id, translation_size); | 497 translation->BeginConstructStubFrame(closure_id, translation_size); |
486 break; | 498 break; |
487 case JS_GETTER: | 499 case JS_GETTER: |
488 ASSERT(translation_size == 1); | 500 ASSERT(translation_size == 1); |
489 ASSERT(height == 0); | 501 ASSERT(height == 0); |
490 translation->BeginGetterStubFrame(closure_id); | 502 translation->BeginGetterStubFrame(closure_id); |
491 break; | 503 break; |
492 case JS_SETTER: | 504 case JS_SETTER: |
493 ASSERT(translation_size == 2); | 505 ASSERT(translation_size == 2); |
494 ASSERT(height == 0); | 506 ASSERT(height == 0); |
495 translation->BeginSetterStubFrame(closure_id); | 507 translation->BeginSetterStubFrame(closure_id); |
496 break; | 508 break; |
497 case ARGUMENTS_ADAPTOR: | 509 case ARGUMENTS_ADAPTOR: |
498 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); | 510 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); |
499 break; | 511 break; |
500 } | 512 } |
| 513 |
| 514 // Inlined frames which push their arguments cause the index to be |
| 515 // bumped and a new stack area to be used for materialization. |
| 516 if (environment->entry() != NULL && |
| 517 environment->entry()->arguments_pushed()) { |
| 518 *arguments_index = *arguments_index < 0 |
| 519 ? GetStackSlotCount() |
| 520 : *arguments_index + *arguments_count; |
| 521 *arguments_count = environment->entry()->arguments_count() + 1; |
| 522 } |
| 523 |
501 for (int i = 0; i < translation_size; ++i) { | 524 for (int i = 0; i < translation_size; ++i) { |
502 LOperand* value = environment->values()->at(i); | 525 LOperand* value = environment->values()->at(i); |
503 // spilled_registers_ and spilled_double_registers_ are either | 526 // spilled_registers_ and spilled_double_registers_ are either |
504 // both NULL or both set. | 527 // both NULL or both set. |
505 if (environment->spilled_registers() != NULL && value != NULL) { | 528 if (environment->spilled_registers() != NULL && value != NULL) { |
506 if (value->IsRegister() && | 529 if (value->IsRegister() && |
507 environment->spilled_registers()[value->index()] != NULL) { | 530 environment->spilled_registers()[value->index()] != NULL) { |
508 translation->MarkDuplicate(); | 531 translation->MarkDuplicate(); |
509 AddToTranslation(translation, | 532 AddToTranslation(translation, |
510 environment->spilled_registers()[value->index()], | 533 environment->spilled_registers()[value->index()], |
511 environment->HasTaggedValueAt(i), | 534 environment->HasTaggedValueAt(i), |
512 environment->HasUint32ValueAt(i)); | 535 environment->HasUint32ValueAt(i), |
| 536 *arguments_index, |
| 537 *arguments_count); |
513 } else if ( | 538 } else if ( |
514 value->IsDoubleRegister() && | 539 value->IsDoubleRegister() && |
515 environment->spilled_double_registers()[value->index()] != NULL) { | 540 environment->spilled_double_registers()[value->index()] != NULL) { |
516 translation->MarkDuplicate(); | 541 translation->MarkDuplicate(); |
517 AddToTranslation( | 542 AddToTranslation( |
518 translation, | 543 translation, |
519 environment->spilled_double_registers()[value->index()], | 544 environment->spilled_double_registers()[value->index()], |
520 false, | 545 false, |
521 false); | 546 false, |
| 547 *arguments_index, |
| 548 *arguments_count); |
522 } | 549 } |
523 } | 550 } |
524 | 551 |
525 AddToTranslation(translation, | 552 AddToTranslation(translation, |
526 value, | 553 value, |
527 environment->HasTaggedValueAt(i), | 554 environment->HasTaggedValueAt(i), |
528 environment->HasUint32ValueAt(i)); | 555 environment->HasUint32ValueAt(i), |
| 556 *arguments_index, |
| 557 *arguments_count); |
529 } | 558 } |
530 } | 559 } |
531 | 560 |
532 | 561 |
533 void LCodeGen::AddToTranslation(Translation* translation, | 562 void LCodeGen::AddToTranslation(Translation* translation, |
534 LOperand* op, | 563 LOperand* op, |
535 bool is_tagged, | 564 bool is_tagged, |
536 bool is_uint32) { | 565 bool is_uint32, |
| 566 int arguments_index, |
| 567 int arguments_count) { |
537 if (op == NULL) { | 568 if (op == NULL) { |
538 // TODO(twuerthinger): Introduce marker operands to indicate that this value | 569 // TODO(twuerthinger): Introduce marker operands to indicate that this value |
539 // is not present and must be reconstructed from the deoptimizer. Currently | 570 // is not present and must be reconstructed from the deoptimizer. Currently |
540 // this is only used for the arguments object. | 571 // this is only used for the arguments object. |
541 translation->StoreArgumentsObject(); | 572 translation->StoreArgumentsObject(arguments_index, arguments_count); |
542 } else if (op->IsStackSlot()) { | 573 } else if (op->IsStackSlot()) { |
543 if (is_tagged) { | 574 if (is_tagged) { |
544 translation->StoreStackSlot(op->index()); | 575 translation->StoreStackSlot(op->index()); |
545 } else if (is_uint32) { | 576 } else if (is_uint32) { |
546 translation->StoreUint32StackSlot(op->index()); | 577 translation->StoreUint32StackSlot(op->index()); |
547 } else { | 578 } else { |
548 translation->StoreInt32StackSlot(op->index()); | 579 translation->StoreInt32StackSlot(op->index()); |
549 } | 580 } |
550 } else if (op->IsDoubleStackSlot()) { | 581 } else if (op->IsDoubleStackSlot()) { |
551 translation->StoreDoubleStackSlot(op->index()); | 582 translation->StoreDoubleStackSlot(op->index()); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 // 0 ..................................................... size-1 | 668 // 0 ..................................................... size-1 |
638 // [parameters] [locals] [expression stack including arguments] | 669 // [parameters] [locals] [expression stack including arguments] |
639 | 670 |
640 // Layout of the translation: | 671 // Layout of the translation: |
641 // 0 ........................................................ size - 1 + 4 | 672 // 0 ........................................................ size - 1 + 4 |
642 // [expression stack including arguments] [locals] [4 words] [parameters] | 673 // [expression stack including arguments] [locals] [4 words] [parameters] |
643 // |>------------ translation_size ------------<| | 674 // |>------------ translation_size ------------<| |
644 | 675 |
645 int frame_count = 0; | 676 int frame_count = 0; |
646 int jsframe_count = 0; | 677 int jsframe_count = 0; |
| 678 int args_index = 0; |
| 679 int args_count = 0; |
647 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { | 680 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { |
648 ++frame_count; | 681 ++frame_count; |
649 if (e->frame_type() == JS_FUNCTION) { | 682 if (e->frame_type() == JS_FUNCTION) { |
650 ++jsframe_count; | 683 ++jsframe_count; |
651 } | 684 } |
652 } | 685 } |
653 Translation translation(&translations_, frame_count, jsframe_count, | 686 Translation translation(&translations_, frame_count, jsframe_count, zone()); |
654 zone()); | 687 WriteTranslation(environment, &translation, &args_index, &args_count); |
655 WriteTranslation(environment, &translation); | |
656 int deoptimization_index = deoptimizations_.length(); | 688 int deoptimization_index = deoptimizations_.length(); |
657 int pc_offset = masm()->pc_offset(); | 689 int pc_offset = masm()->pc_offset(); |
658 environment->Register(deoptimization_index, | 690 environment->Register(deoptimization_index, |
659 translation.index(), | 691 translation.index(), |
660 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); | 692 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); |
661 deoptimizations_.Add(environment, zone()); | 693 deoptimizations_.Add(environment, zone()); |
662 } | 694 } |
663 } | 695 } |
664 | 696 |
665 | 697 |
(...skipping 4952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5618 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 5650 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
5619 __ ldr(result, FieldMemOperand(scratch, | 5651 __ ldr(result, FieldMemOperand(scratch, |
5620 FixedArray::kHeaderSize - kPointerSize)); | 5652 FixedArray::kHeaderSize - kPointerSize)); |
5621 __ bind(&done); | 5653 __ bind(&done); |
5622 } | 5654 } |
5623 | 5655 |
5624 | 5656 |
5625 #undef __ | 5657 #undef __ |
5626 | 5658 |
5627 } } // namespace v8::internal | 5659 } } // namespace v8::internal |
OLD | NEW |