| 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 |