| 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 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } | 573 } |
| 574 | 574 |
| 575 | 575 |
| 576 MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { | 576 MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { |
| 577 ASSERT(op->IsDoubleStackSlot()); | 577 ASSERT(op->IsDoubleStackSlot()); |
| 578 return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize); | 578 return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize); |
| 579 } | 579 } |
| 580 | 580 |
| 581 | 581 |
| 582 void LCodeGen::WriteTranslation(LEnvironment* environment, | 582 void LCodeGen::WriteTranslation(LEnvironment* environment, |
| 583 Translation* translation, | 583 Translation* translation) { |
| 584 int* pushed_arguments_index, | |
| 585 int* pushed_arguments_count) { | |
| 586 if (environment == NULL) return; | 584 if (environment == NULL) return; |
| 587 | 585 |
| 588 // The translation includes one command per value in the environment. | 586 // The translation includes one command per value in the environment. |
| 589 int translation_size = environment->values()->length(); | 587 int translation_size = environment->translation_size(); |
| 590 // The output frame height does not include the parameters. | 588 // The output frame height does not include the parameters. |
| 591 int height = translation_size - environment->parameter_count(); | 589 int height = translation_size - environment->parameter_count(); |
| 592 | 590 |
| 593 // Function parameters are arguments to the outermost environment. The | 591 WriteTranslation(environment->outer(), translation); |
| 594 // arguments index points to the first element of a sequence of tagged | |
| 595 // values on the stack that represent the arguments. This needs to be | |
| 596 // kept in sync with the LArgumentsElements implementation. | |
| 597 *pushed_arguments_index = -environment->parameter_count(); | |
| 598 *pushed_arguments_count = environment->parameter_count(); | |
| 599 | |
| 600 WriteTranslation(environment->outer(), | |
| 601 translation, | |
| 602 pushed_arguments_index, | |
| 603 pushed_arguments_count); | |
| 604 bool has_closure_id = !info()->closure().is_null() && | 592 bool has_closure_id = !info()->closure().is_null() && |
| 605 !info()->closure().is_identical_to(environment->closure()); | 593 !info()->closure().is_identical_to(environment->closure()); |
| 606 int closure_id = has_closure_id | 594 int closure_id = has_closure_id |
| 607 ? DefineDeoptimizationLiteral(environment->closure()) | 595 ? DefineDeoptimizationLiteral(environment->closure()) |
| 608 : Translation::kSelfLiteralId; | 596 : Translation::kSelfLiteralId; |
| 609 | 597 |
| 610 switch (environment->frame_type()) { | 598 switch (environment->frame_type()) { |
| 611 case JS_FUNCTION: | 599 case JS_FUNCTION: |
| 612 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 600 translation->BeginJSFrame(environment->ast_id(), closure_id, height); |
| 613 break; | 601 break; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 625 translation->BeginSetterStubFrame(closure_id); | 613 translation->BeginSetterStubFrame(closure_id); |
| 626 break; | 614 break; |
| 627 case STUB: | 615 case STUB: |
| 628 translation->BeginCompiledStubFrame(); | 616 translation->BeginCompiledStubFrame(); |
| 629 break; | 617 break; |
| 630 case ARGUMENTS_ADAPTOR: | 618 case ARGUMENTS_ADAPTOR: |
| 631 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); | 619 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); |
| 632 break; | 620 break; |
| 633 } | 621 } |
| 634 | 622 |
| 635 // Inlined frames which push their arguments cause the index to be | |
| 636 // bumped and another stack area to be used for materialization, | |
| 637 // otherwise actual argument values are unknown for inlined frames. | |
| 638 bool arguments_known = true; | |
| 639 int arguments_index = *pushed_arguments_index; | |
| 640 int arguments_count = *pushed_arguments_count; | |
| 641 if (environment->entry() != NULL) { | |
| 642 arguments_known = environment->entry()->arguments_pushed(); | |
| 643 arguments_index = arguments_index < 0 | |
| 644 ? GetStackSlotCount() : arguments_index + arguments_count; | |
| 645 arguments_count = environment->entry()->arguments_count() + 1; | |
| 646 if (environment->entry()->arguments_pushed()) { | |
| 647 *pushed_arguments_index = arguments_index; | |
| 648 *pushed_arguments_count = arguments_count; | |
| 649 } | |
| 650 } | |
| 651 | |
| 652 for (int i = 0; i < translation_size; ++i) { | 623 for (int i = 0; i < translation_size; ++i) { |
| 653 LOperand* value = environment->values()->at(i); | 624 LOperand* value = environment->values()->at(i); |
| 654 // spilled_registers_ and spilled_double_registers_ are either | 625 // spilled_registers_ and spilled_double_registers_ are either |
| 655 // both NULL or both set. | 626 // both NULL or both set. |
| 656 if (environment->spilled_registers() != NULL && value != NULL) { | 627 if (environment->spilled_registers() != NULL && value != NULL) { |
| 657 if (value->IsRegister() && | 628 if (value->IsRegister() && |
| 658 environment->spilled_registers()[value->index()] != NULL) { | 629 environment->spilled_registers()[value->index()] != NULL) { |
| 659 translation->MarkDuplicate(); | 630 translation->MarkDuplicate(); |
| 660 AddToTranslation(translation, | 631 AddToTranslation(translation, |
| 661 environment->spilled_registers()[value->index()], | 632 environment->spilled_registers()[value->index()], |
| 662 environment->HasTaggedValueAt(i), | 633 environment->HasTaggedValueAt(i), |
| 663 environment->HasUint32ValueAt(i), | 634 environment->HasUint32ValueAt(i)); |
| 664 arguments_known, | |
| 665 arguments_index, | |
| 666 arguments_count); | |
| 667 } else if ( | 635 } else if ( |
| 668 value->IsDoubleRegister() && | 636 value->IsDoubleRegister() && |
| 669 environment->spilled_double_registers()[value->index()] != NULL) { | 637 environment->spilled_double_registers()[value->index()] != NULL) { |
| 670 translation->MarkDuplicate(); | 638 translation->MarkDuplicate(); |
| 671 AddToTranslation( | 639 AddToTranslation( |
| 672 translation, | 640 translation, |
| 673 environment->spilled_double_registers()[value->index()], | 641 environment->spilled_double_registers()[value->index()], |
| 674 false, | 642 false, |
| 675 false, | 643 false); |
| 676 arguments_known, | |
| 677 arguments_index, | |
| 678 arguments_count); | |
| 679 } | 644 } |
| 680 } | 645 } |
| 681 | 646 |
| 647 // TODO(mstarzinger): Introduce marker operands to indicate that this value |
| 648 // is not present and must be reconstructed from the deoptimizer. Currently |
| 649 // this is only used for the arguments object. |
| 650 if (value == NULL) { |
| 651 int arguments_count = environment->values()->length() - translation_size; |
| 652 translation->BeginArgumentsObject(arguments_count); |
| 653 for (int i = 0; i < arguments_count; ++i) { |
| 654 LOperand* value = environment->values()->at(translation_size + i); |
| 655 ASSERT(environment->spilled_registers() == NULL || |
| 656 !value->IsRegister() || |
| 657 environment->spilled_registers()[value->index()] == NULL); |
| 658 ASSERT(environment->spilled_registers() == NULL || |
| 659 !value->IsDoubleRegister() || |
| 660 environment->spilled_double_registers()[value->index()] == NULL); |
| 661 AddToTranslation(translation, |
| 662 value, |
| 663 environment->HasTaggedValueAt(translation_size + i), |
| 664 environment->HasUint32ValueAt(translation_size + i)); |
| 665 } |
| 666 continue; |
| 667 } |
| 668 |
| 682 AddToTranslation(translation, | 669 AddToTranslation(translation, |
| 683 value, | 670 value, |
| 684 environment->HasTaggedValueAt(i), | 671 environment->HasTaggedValueAt(i), |
| 685 environment->HasUint32ValueAt(i), | 672 environment->HasUint32ValueAt(i)); |
| 686 arguments_known, | |
| 687 arguments_index, | |
| 688 arguments_count); | |
| 689 } | 673 } |
| 690 } | 674 } |
| 691 | 675 |
| 692 | 676 |
| 693 void LCodeGen::AddToTranslation(Translation* translation, | 677 void LCodeGen::AddToTranslation(Translation* translation, |
| 694 LOperand* op, | 678 LOperand* op, |
| 695 bool is_tagged, | 679 bool is_tagged, |
| 696 bool is_uint32, | 680 bool is_uint32) { |
| 697 bool arguments_known, | 681 if (op->IsStackSlot()) { |
| 698 int arguments_index, | |
| 699 int arguments_count) { | |
| 700 if (op == NULL) { | |
| 701 // TODO(twuerthinger): Introduce marker operands to indicate that this value | |
| 702 // is not present and must be reconstructed from the deoptimizer. Currently | |
| 703 // this is only used for the arguments object. | |
| 704 translation->StoreArgumentsObject( | |
| 705 arguments_known, arguments_index, arguments_count); | |
| 706 } else if (op->IsStackSlot()) { | |
| 707 if (is_tagged) { | 682 if (is_tagged) { |
| 708 translation->StoreStackSlot(op->index()); | 683 translation->StoreStackSlot(op->index()); |
| 709 } else if (is_uint32) { | 684 } else if (is_uint32) { |
| 710 translation->StoreUint32StackSlot(op->index()); | 685 translation->StoreUint32StackSlot(op->index()); |
| 711 } else { | 686 } else { |
| 712 translation->StoreInt32StackSlot(op->index()); | 687 translation->StoreInt32StackSlot(op->index()); |
| 713 } | 688 } |
| 714 } else if (op->IsDoubleStackSlot()) { | 689 } else if (op->IsDoubleStackSlot()) { |
| 715 translation->StoreDoubleStackSlot(op->index()); | 690 translation->StoreDoubleStackSlot(op->index()); |
| 716 } else if (op->IsArgument()) { | 691 } else if (op->IsArgument()) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 // 0 ..................................................... size-1 | 778 // 0 ..................................................... size-1 |
| 804 // [parameters] [locals] [expression stack including arguments] | 779 // [parameters] [locals] [expression stack including arguments] |
| 805 | 780 |
| 806 // Layout of the translation: | 781 // Layout of the translation: |
| 807 // 0 ........................................................ size - 1 + 4 | 782 // 0 ........................................................ size - 1 + 4 |
| 808 // [expression stack including arguments] [locals] [4 words] [parameters] | 783 // [expression stack including arguments] [locals] [4 words] [parameters] |
| 809 // |>------------ translation_size ------------<| | 784 // |>------------ translation_size ------------<| |
| 810 | 785 |
| 811 int frame_count = 0; | 786 int frame_count = 0; |
| 812 int jsframe_count = 0; | 787 int jsframe_count = 0; |
| 813 int args_index = 0; | |
| 814 int args_count = 0; | |
| 815 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { | 788 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { |
| 816 ++frame_count; | 789 ++frame_count; |
| 817 if (e->frame_type() == JS_FUNCTION) { | 790 if (e->frame_type() == JS_FUNCTION) { |
| 818 ++jsframe_count; | 791 ++jsframe_count; |
| 819 } | 792 } |
| 820 } | 793 } |
| 821 Translation translation(&translations_, frame_count, jsframe_count, zone()); | 794 Translation translation(&translations_, frame_count, jsframe_count, zone()); |
| 822 WriteTranslation(environment, &translation, &args_index, &args_count); | 795 WriteTranslation(environment, &translation); |
| 823 int deoptimization_index = deoptimizations_.length(); | 796 int deoptimization_index = deoptimizations_.length(); |
| 824 int pc_offset = masm()->pc_offset(); | 797 int pc_offset = masm()->pc_offset(); |
| 825 environment->Register(deoptimization_index, | 798 environment->Register(deoptimization_index, |
| 826 translation.index(), | 799 translation.index(), |
| 827 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); | 800 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); |
| 828 deoptimizations_.Add(environment, zone()); | 801 deoptimizations_.Add(environment, zone()); |
| 829 } | 802 } |
| 830 } | 803 } |
| 831 | 804 |
| 832 | 805 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 845 } | 818 } |
| 846 | 819 |
| 847 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. | 820 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. |
| 848 if (FLAG_deopt_every_n_times == 1 && | 821 if (FLAG_deopt_every_n_times == 1 && |
| 849 !info()->IsStub() && | 822 !info()->IsStub() && |
| 850 info()->opt_count() == id) { | 823 info()->opt_count() == id) { |
| 851 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); | 824 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); |
| 852 return; | 825 return; |
| 853 } | 826 } |
| 854 | 827 |
| 855 if (FLAG_trap_on_deopt) { | 828 if (FLAG_trap_on_deopt && info()->IsOptimizing()) { |
| 856 __ stop("trap_on_deopt", cc); | 829 __ stop("trap_on_deopt", cc); |
| 857 } | 830 } |
| 858 | 831 |
| 859 ASSERT(info()->IsStub() || frame_is_built_); | 832 ASSERT(info()->IsStub() || frame_is_built_); |
| 860 bool needs_lazy_deopt = info()->IsStub(); | 833 bool needs_lazy_deopt = info()->IsStub(); |
| 861 if (cc == al && frame_is_built_) { | 834 if (cc == al && frame_is_built_) { |
| 862 if (needs_lazy_deopt) { | 835 if (needs_lazy_deopt) { |
| 863 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | 836 __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| 864 } else { | 837 } else { |
| 865 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); | 838 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); |
| (...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2782 __ ldr(map, FieldMemOperand(object, HeapObject::kMapOffset)); | 2755 __ ldr(map, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 2783 { | 2756 { |
| 2784 // Block constant pool emission to ensure the positions of instructions are | 2757 // Block constant pool emission to ensure the positions of instructions are |
| 2785 // as expected by the patcher. See InstanceofStub::Generate(). | 2758 // as expected by the patcher. See InstanceofStub::Generate(). |
| 2786 Assembler::BlockConstPoolScope block_const_pool(masm()); | 2759 Assembler::BlockConstPoolScope block_const_pool(masm()); |
| 2787 __ bind(deferred->map_check()); // Label for calculating code patching. | 2760 __ bind(deferred->map_check()); // Label for calculating code patching. |
| 2788 // We use Factory::the_hole_value() on purpose instead of loading from the | 2761 // We use Factory::the_hole_value() on purpose instead of loading from the |
| 2789 // root array to force relocation to be able to later patch with | 2762 // root array to force relocation to be able to later patch with |
| 2790 // the cached map. | 2763 // the cached map. |
| 2791 PredictableCodeSizeScope predictable(masm_, 5 * Assembler::kInstrSize); | 2764 PredictableCodeSizeScope predictable(masm_, 5 * Assembler::kInstrSize); |
| 2792 Handle<JSGlobalPropertyCell> cell = | 2765 Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value()); |
| 2793 factory()->NewJSGlobalPropertyCell(factory()->the_hole_value()); | |
| 2794 __ mov(ip, Operand(Handle<Object>(cell))); | 2766 __ mov(ip, Operand(Handle<Object>(cell))); |
| 2795 __ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); | 2767 __ ldr(ip, FieldMemOperand(ip, PropertyCell::kValueOffset)); |
| 2796 __ cmp(map, Operand(ip)); | 2768 __ cmp(map, Operand(ip)); |
| 2797 __ b(ne, &cache_miss); | 2769 __ b(ne, &cache_miss); |
| 2798 // We use Factory::the_hole_value() on purpose instead of loading from the | 2770 // We use Factory::the_hole_value() on purpose instead of loading from the |
| 2799 // root array to force relocation to be able to later patch | 2771 // root array to force relocation to be able to later patch |
| 2800 // with true or false. | 2772 // with true or false. |
| 2801 __ mov(result, Operand(factory()->the_hole_value())); | 2773 __ mov(result, Operand(factory()->the_hole_value())); |
| 2802 } | 2774 } |
| 2803 __ b(&done); | 2775 __ b(&done); |
| 2804 | 2776 |
| 2805 // The inlined call site cache did not match. Check null and string before | 2777 // The inlined call site cache did not match. Check null and string before |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2945 | 2917 |
| 2946 if (no_frame_start != -1) { | 2918 if (no_frame_start != -1) { |
| 2947 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 2919 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 2948 } | 2920 } |
| 2949 } | 2921 } |
| 2950 | 2922 |
| 2951 | 2923 |
| 2952 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 2924 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { |
| 2953 Register result = ToRegister(instr->result()); | 2925 Register result = ToRegister(instr->result()); |
| 2954 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); | 2926 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); |
| 2955 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); | 2927 __ ldr(result, FieldMemOperand(ip, Cell::kValueOffset)); |
| 2956 if (instr->hydrogen()->RequiresHoleCheck()) { | 2928 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2957 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2929 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 2958 __ cmp(result, ip); | 2930 __ cmp(result, ip); |
| 2959 DeoptimizeIf(eq, instr->environment()); | 2931 DeoptimizeIf(eq, instr->environment()); |
| 2960 } | 2932 } |
| 2961 } | 2933 } |
| 2962 | 2934 |
| 2963 | 2935 |
| 2964 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2936 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { |
| 2965 ASSERT(ToRegister(instr->global_object()).is(r0)); | 2937 ASSERT(ToRegister(instr->global_object()).is(r0)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2980 // Load the cell. | 2952 // Load the cell. |
| 2981 __ mov(cell, Operand(instr->hydrogen()->cell())); | 2953 __ mov(cell, Operand(instr->hydrogen()->cell())); |
| 2982 | 2954 |
| 2983 // If the cell we are storing to contains the hole it could have | 2955 // If the cell we are storing to contains the hole it could have |
| 2984 // been deleted from the property dictionary. In that case, we need | 2956 // been deleted from the property dictionary. In that case, we need |
| 2985 // to update the property details in the property dictionary to mark | 2957 // to update the property details in the property dictionary to mark |
| 2986 // it as no longer deleted. | 2958 // it as no longer deleted. |
| 2987 if (instr->hydrogen()->RequiresHoleCheck()) { | 2959 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2988 // We use a temp to check the payload (CompareRoot might clobber ip). | 2960 // We use a temp to check the payload (CompareRoot might clobber ip). |
| 2989 Register payload = ToRegister(instr->temp()); | 2961 Register payload = ToRegister(instr->temp()); |
| 2990 __ ldr(payload, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); | 2962 __ ldr(payload, FieldMemOperand(cell, Cell::kValueOffset)); |
| 2991 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); | 2963 __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); |
| 2992 DeoptimizeIf(eq, instr->environment()); | 2964 DeoptimizeIf(eq, instr->environment()); |
| 2993 } | 2965 } |
| 2994 | 2966 |
| 2995 // Store the value. | 2967 // Store the value. |
| 2996 __ str(value, FieldMemOperand(cell, JSGlobalPropertyCell::kValueOffset)); | 2968 __ str(value, FieldMemOperand(cell, Cell::kValueOffset)); |
| 2997 // Cells are always rescanned, so no write barrier here. | 2969 // Cells are always rescanned, so no write barrier here. |
| 2998 } | 2970 } |
| 2999 | 2971 |
| 3000 | 2972 |
| 3001 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | 2973 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { |
| 3002 ASSERT(ToRegister(instr->global_object()).is(r1)); | 2974 ASSERT(ToRegister(instr->global_object()).is(r1)); |
| 3003 ASSERT(ToRegister(instr->value()).is(r0)); | 2975 ASSERT(ToRegister(instr->value()).is(r0)); |
| 3004 | 2976 |
| 3005 __ mov(r2, Operand(instr->name())); | 2977 __ mov(r2, Operand(instr->name())); |
| 3006 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 2978 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| (...skipping 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4199 __ mov(r0, Operand(instr->arity())); | 4171 __ mov(r0, Operand(instr->arity())); |
| 4200 __ mov(r2, Operand(instr->hydrogen()->property_cell())); | 4172 __ mov(r2, Operand(instr->hydrogen()->property_cell())); |
| 4201 ElementsKind kind = instr->hydrogen()->elements_kind(); | 4173 ElementsKind kind = instr->hydrogen()->elements_kind(); |
| 4202 bool disable_allocation_sites = | 4174 bool disable_allocation_sites = |
| 4203 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); | 4175 (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE); |
| 4204 | 4176 |
| 4205 if (instr->arity() == 0) { | 4177 if (instr->arity() == 0) { |
| 4206 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); | 4178 ArrayNoArgumentConstructorStub stub(kind, disable_allocation_sites); |
| 4207 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4179 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4208 } else if (instr->arity() == 1) { | 4180 } else if (instr->arity() == 1) { |
| 4181 Label done; |
| 4182 if (IsFastPackedElementsKind(kind)) { |
| 4183 Label packed_case; |
| 4184 // We might need a change here |
| 4185 // look at the first argument |
| 4186 __ ldr(r5, MemOperand(sp, 0)); |
| 4187 __ cmp(r5, Operand::Zero()); |
| 4188 __ b(eq, &packed_case); |
| 4189 |
| 4190 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
| 4191 ArraySingleArgumentConstructorStub stub(holey_kind, |
| 4192 disable_allocation_sites); |
| 4193 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4194 __ jmp(&done); |
| 4195 __ bind(&packed_case); |
| 4196 } |
| 4197 |
| 4209 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); | 4198 ArraySingleArgumentConstructorStub stub(kind, disable_allocation_sites); |
| 4210 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4199 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4200 __ bind(&done); |
| 4211 } else { | 4201 } else { |
| 4212 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); | 4202 ArrayNArgumentsConstructorStub stub(kind, disable_allocation_sites); |
| 4213 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4203 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4214 } | 4204 } |
| 4215 } | 4205 } |
| 4216 | 4206 |
| 4217 | 4207 |
| 4218 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 4208 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
| 4219 CallRuntime(instr->function(), instr->arity(), instr); | 4209 CallRuntime(instr->function(), instr->arity(), instr); |
| 4220 } | 4210 } |
| (...skipping 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5256 } | 5246 } |
| 5257 } | 5247 } |
| 5258 | 5248 |
| 5259 | 5249 |
| 5260 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 5250 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 5261 Register reg = ToRegister(instr->value()); | 5251 Register reg = ToRegister(instr->value()); |
| 5262 Handle<JSFunction> target = instr->hydrogen()->target(); | 5252 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 5263 AllowDeferredHandleDereference smi_check; | 5253 AllowDeferredHandleDereference smi_check; |
| 5264 if (isolate()->heap()->InNewSpace(*target)) { | 5254 if (isolate()->heap()->InNewSpace(*target)) { |
| 5265 Register reg = ToRegister(instr->value()); | 5255 Register reg = ToRegister(instr->value()); |
| 5266 Handle<JSGlobalPropertyCell> cell = | 5256 Handle<Cell> cell = isolate()->factory()->NewPropertyCell(target); |
| 5267 isolate()->factory()->NewJSGlobalPropertyCell(target); | |
| 5268 __ mov(ip, Operand(Handle<Object>(cell))); | 5257 __ mov(ip, Operand(Handle<Object>(cell))); |
| 5269 __ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); | 5258 __ ldr(ip, FieldMemOperand(ip, Cell::kValueOffset)); |
| 5270 __ cmp(reg, ip); | 5259 __ cmp(reg, ip); |
| 5271 } else { | 5260 } else { |
| 5272 __ cmp(reg, Operand(target)); | 5261 __ cmp(reg, Operand(target)); |
| 5273 } | 5262 } |
| 5274 DeoptimizeIf(ne, instr->environment()); | 5263 DeoptimizeIf(ne, instr->environment()); |
| 5275 } | 5264 } |
| 5276 | 5265 |
| 5277 | 5266 |
| 5278 void LCodeGen::DoCheckMapCommon(Register map_reg, | 5267 void LCodeGen::DoCheckMapCommon(Register map_reg, |
| 5279 Handle<Map> map, | 5268 Handle<Map> map, |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5891 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5880 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5892 __ ldr(result, FieldMemOperand(scratch, | 5881 __ ldr(result, FieldMemOperand(scratch, |
| 5893 FixedArray::kHeaderSize - kPointerSize)); | 5882 FixedArray::kHeaderSize - kPointerSize)); |
| 5894 __ bind(&done); | 5883 __ bind(&done); |
| 5895 } | 5884 } |
| 5896 | 5885 |
| 5897 | 5886 |
| 5898 #undef __ | 5887 #undef __ |
| 5899 | 5888 |
| 5900 } } // namespace v8::internal | 5889 } } // namespace v8::internal |
| OLD | NEW |