| OLD | NEW | 
|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 23 matching lines...) Expand all  Loading... | 
| 34 #include "register-allocator-inl.h" | 34 #include "register-allocator-inl.h" | 
| 35 #include "runtime.h" | 35 #include "runtime.h" | 
| 36 #include "scopes.h" | 36 #include "scopes.h" | 
| 37 | 37 | 
| 38 | 38 | 
| 39 namespace v8 { | 39 namespace v8 { | 
| 40 namespace internal { | 40 namespace internal { | 
| 41 | 41 | 
| 42 #define __ ACCESS_MASM(masm_) | 42 #define __ ACCESS_MASM(masm_) | 
| 43 | 43 | 
|  | 44 // ------------------------------------------------------------------------- | 
|  | 45 // Platform-specific DeferredCode functions. | 
|  | 46 | 
|  | 47 void DeferredCode::SaveRegisters() { | 
|  | 48   for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { | 
|  | 49     int action = registers_[i]; | 
|  | 50     if (action == kPush) { | 
|  | 51       __ push(RegisterAllocator::ToRegister(i)); | 
|  | 52     } else if (action != kIgnore && (action & kSyncedFlag) == 0) { | 
|  | 53       __ str(RegisterAllocator::ToRegister(i), MemOperand(fp, action)); | 
|  | 54     } | 
|  | 55   } | 
|  | 56 } | 
|  | 57 | 
|  | 58 | 
|  | 59 void DeferredCode::RestoreRegisters() { | 
|  | 60   // Restore registers in reverse order due to the stack. | 
|  | 61   for (int i = RegisterAllocator::kNumRegisters - 1; i >= 0; i--) { | 
|  | 62     int action = registers_[i]; | 
|  | 63     if (action == kPush) { | 
|  | 64       __ pop(RegisterAllocator::ToRegister(i)); | 
|  | 65     } else if (action != kIgnore) { | 
|  | 66       action &= ~kSyncedFlag; | 
|  | 67       __ ldr(RegisterAllocator::ToRegister(i), MemOperand(fp, action)); | 
|  | 68     } | 
|  | 69   } | 
|  | 70 } | 
|  | 71 | 
| 44 | 72 | 
| 45 // ------------------------------------------------------------------------- | 73 // ------------------------------------------------------------------------- | 
| 46 // CodeGenState implementation. | 74 // CodeGenState implementation. | 
| 47 | 75 | 
| 48 CodeGenState::CodeGenState(CodeGenerator* owner) | 76 CodeGenState::CodeGenState(CodeGenerator* owner) | 
| 49     : owner_(owner), | 77     : owner_(owner), | 
| 50       typeof_state_(NOT_INSIDE_TYPEOF), | 78       typeof_state_(NOT_INSIDE_TYPEOF), | 
| 51       true_target_(NULL), | 79       true_target_(NULL), | 
| 52       false_target_(NULL), | 80       false_target_(NULL), | 
| 53       previous_(NULL) { | 81       previous_(NULL) { | 
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 769   virtual void Generate(); | 797   virtual void Generate(); | 
| 770 | 798 | 
| 771  private: | 799  private: | 
| 772   Token::Value op_; | 800   Token::Value op_; | 
| 773   int value_; | 801   int value_; | 
| 774   bool reversed_; | 802   bool reversed_; | 
| 775   OverwriteMode overwrite_mode_; | 803   OverwriteMode overwrite_mode_; | 
| 776 }; | 804 }; | 
| 777 | 805 | 
| 778 | 806 | 
| 779 #undef __ |  | 
| 780 #define __ ACCESS_MASM(masm) |  | 
| 781 |  | 
| 782 |  | 
| 783 void DeferredInlineSmiOperation::Generate() { | 807 void DeferredInlineSmiOperation::Generate() { | 
| 784   MacroAssembler* masm = cgen()->masm(); |  | 
| 785   enter()->Bind(); |  | 
| 786   VirtualFrame::SpilledScope spilled_scope; |  | 
| 787 |  | 
| 788   switch (op_) { | 808   switch (op_) { | 
| 789     case Token::ADD: { | 809     case Token::ADD: { | 
|  | 810       // Revert optimistic add. | 
| 790       if (reversed_) { | 811       if (reversed_) { | 
| 791         // revert optimistic add |  | 
| 792         __ sub(r0, r0, Operand(Smi::FromInt(value_))); | 812         __ sub(r0, r0, Operand(Smi::FromInt(value_))); | 
| 793         __ mov(r1, Operand(Smi::FromInt(value_))); | 813         __ mov(r1, Operand(Smi::FromInt(value_))); | 
| 794       } else { | 814       } else { | 
| 795         // revert optimistic add |  | 
| 796         __ sub(r1, r0, Operand(Smi::FromInt(value_))); | 815         __ sub(r1, r0, Operand(Smi::FromInt(value_))); | 
| 797         __ mov(r0, Operand(Smi::FromInt(value_))); | 816         __ mov(r0, Operand(Smi::FromInt(value_))); | 
| 798       } | 817       } | 
| 799       break; | 818       break; | 
| 800     } | 819     } | 
| 801 | 820 | 
| 802     case Token::SUB: { | 821     case Token::SUB: { | 
|  | 822       // Revert optimistic sub. | 
| 803       if (reversed_) { | 823       if (reversed_) { | 
| 804         // revert optimistic sub |  | 
| 805         __ rsb(r0, r0, Operand(Smi::FromInt(value_))); | 824         __ rsb(r0, r0, Operand(Smi::FromInt(value_))); | 
| 806         __ mov(r1, Operand(Smi::FromInt(value_))); | 825         __ mov(r1, Operand(Smi::FromInt(value_))); | 
| 807       } else { | 826       } else { | 
| 808         __ add(r1, r0, Operand(Smi::FromInt(value_))); | 827         __ add(r1, r0, Operand(Smi::FromInt(value_))); | 
| 809         __ mov(r0, Operand(Smi::FromInt(value_))); | 828         __ mov(r0, Operand(Smi::FromInt(value_))); | 
| 810       } | 829       } | 
| 811       break; | 830       break; | 
| 812     } | 831     } | 
| 813 | 832 | 
| 814     case Token::BIT_OR: | 833     case Token::BIT_OR: | 
| 815     case Token::BIT_XOR: | 834     case Token::BIT_XOR: | 
| 816     case Token::BIT_AND: { | 835     case Token::BIT_AND: { | 
| 817       if (reversed_) { | 836       if (reversed_) { | 
| 818         __ mov(r1, Operand(Smi::FromInt(value_))); | 837         __ mov(r1, Operand(Smi::FromInt(value_))); | 
| 819       } else { | 838       } else { | 
| 820         __ mov(r1, Operand(r0)); | 839         __ mov(r1, Operand(r0)); | 
| 821         __ mov(r0, Operand(Smi::FromInt(value_))); | 840         __ mov(r0, Operand(Smi::FromInt(value_))); | 
| 822       } | 841       } | 
| 823       break; | 842       break; | 
| 824     } | 843     } | 
| 825 | 844 | 
| 826     case Token::SHL: | 845     case Token::SHL: | 
| 827     case Token::SHR: | 846     case Token::SHR: | 
| 828     case Token::SAR: { | 847     case Token::SAR: { | 
| 829       if (!reversed_) { | 848       if (!reversed_) { | 
| 830         __ mov(r1, Operand(r0)); | 849         __ mov(r1, Operand(r0)); | 
| 831         __ mov(r0, Operand(Smi::FromInt(value_))); | 850         __ mov(r0, Operand(Smi::FromInt(value_))); | 
| 832       } else { | 851       } else { | 
| 833         UNREACHABLE();  // should have been handled in SmiOperation | 852         UNREACHABLE();  // Should have been handled in SmiOperation. | 
| 834       } | 853       } | 
| 835       break; | 854       break; | 
| 836     } | 855     } | 
| 837 | 856 | 
| 838     default: | 857     default: | 
| 839       // other cases should have been handled before this point. | 858       // Other cases should have been handled before this point. | 
| 840       UNREACHABLE(); | 859       UNREACHABLE(); | 
| 841       break; | 860       break; | 
| 842   } | 861   } | 
| 843 | 862 | 
| 844   GenericBinaryOpStub igostub(op_, overwrite_mode_); | 863   GenericBinaryOpStub stub(op_, overwrite_mode_); | 
| 845   Result arg0 = cgen()->allocator()->Allocate(r1); | 864   __ CallStub(&stub); | 
| 846   ASSERT(arg0.is_valid()); |  | 
| 847   Result arg1 = cgen()->allocator()->Allocate(r0); |  | 
| 848   ASSERT(arg1.is_valid()); |  | 
| 849   cgen()->frame()->CallStub(&igostub, &arg0, &arg1); |  | 
| 850   exit_.Jump(); |  | 
| 851 } | 865 } | 
| 852 | 866 | 
| 853 | 867 | 
| 854 #undef __ |  | 
| 855 #define __ ACCESS_MASM(masm_) |  | 
| 856 |  | 
| 857 |  | 
| 858 void CodeGenerator::SmiOperation(Token::Value op, | 868 void CodeGenerator::SmiOperation(Token::Value op, | 
| 859                                  Handle<Object> value, | 869                                  Handle<Object> value, | 
| 860                                  bool reversed, | 870                                  bool reversed, | 
| 861                                  OverwriteMode mode) { | 871                                  OverwriteMode mode) { | 
| 862   VirtualFrame::SpilledScope spilled_scope; | 872   VirtualFrame::SpilledScope spilled_scope; | 
| 863   // NOTE: This is an attempt to inline (a bit) more of the code for | 873   // NOTE: This is an attempt to inline (a bit) more of the code for | 
| 864   // some possible smi operations (like + and -) when (at least) one | 874   // some possible smi operations (like + and -) when (at least) one | 
| 865   // of the operands is a literal smi. With this optimization, the | 875   // of the operands is a literal smi. With this optimization, the | 
| 866   // performance of the system is increased by ~15%, and the generated | 876   // performance of the system is increased by ~15%, and the generated | 
| 867   // code size is increased by ~1% (measured on a combination of | 877   // code size is increased by ~1% (measured on a combination of | 
| 868   // different benchmarks). | 878   // different benchmarks). | 
| 869 | 879 | 
| 870   // sp[0] : operand | 880   // sp[0] : operand | 
| 871 | 881 | 
| 872   int int_value = Smi::cast(*value)->value(); | 882   int int_value = Smi::cast(*value)->value(); | 
| 873 | 883 | 
| 874   JumpTarget exit; | 884   JumpTarget exit; | 
| 875   frame_->EmitPop(r0); | 885   frame_->EmitPop(r0); | 
| 876 | 886 | 
| 877   switch (op) { | 887   switch (op) { | 
| 878     case Token::ADD: { | 888     case Token::ADD: { | 
| 879       DeferredCode* deferred = | 889       DeferredCode* deferred = | 
| 880         new DeferredInlineSmiOperation(op, int_value, reversed, mode); | 890           new DeferredInlineSmiOperation(op, int_value, reversed, mode); | 
| 881 | 891 | 
| 882       __ add(r0, r0, Operand(value), SetCC); | 892       __ add(r0, r0, Operand(value), SetCC); | 
| 883       deferred->enter()->Branch(vs); | 893       deferred->Branch(vs); | 
| 884       __ tst(r0, Operand(kSmiTagMask)); | 894       __ tst(r0, Operand(kSmiTagMask)); | 
| 885       deferred->enter()->Branch(ne); | 895       deferred->Branch(ne); | 
| 886       deferred->BindExit(); | 896       deferred->BindExit(); | 
| 887       break; | 897       break; | 
| 888     } | 898     } | 
| 889 | 899 | 
| 890     case Token::SUB: { | 900     case Token::SUB: { | 
| 891       DeferredCode* deferred = | 901       DeferredCode* deferred = | 
| 892         new DeferredInlineSmiOperation(op, int_value, reversed, mode); | 902           new DeferredInlineSmiOperation(op, int_value, reversed, mode); | 
| 893 | 903 | 
| 894       if (!reversed) { | 904       if (reversed) { | 
|  | 905         __ rsb(r0, r0, Operand(value), SetCC); | 
|  | 906       } else { | 
| 895         __ sub(r0, r0, Operand(value), SetCC); | 907         __ sub(r0, r0, Operand(value), SetCC); | 
| 896       } else { |  | 
| 897         __ rsb(r0, r0, Operand(value), SetCC); |  | 
| 898       } | 908       } | 
| 899       deferred->enter()->Branch(vs); | 909       deferred->Branch(vs); | 
| 900       __ tst(r0, Operand(kSmiTagMask)); | 910       __ tst(r0, Operand(kSmiTagMask)); | 
| 901       deferred->enter()->Branch(ne); | 911       deferred->Branch(ne); | 
| 902       deferred->BindExit(); | 912       deferred->BindExit(); | 
| 903       break; | 913       break; | 
| 904     } | 914     } | 
| 905 | 915 | 
| 906     case Token::BIT_OR: | 916     case Token::BIT_OR: | 
| 907     case Token::BIT_XOR: | 917     case Token::BIT_XOR: | 
| 908     case Token::BIT_AND: { | 918     case Token::BIT_AND: { | 
| 909       DeferredCode* deferred = | 919       DeferredCode* deferred = | 
| 910         new DeferredInlineSmiOperation(op, int_value, reversed, mode); | 920         new DeferredInlineSmiOperation(op, int_value, reversed, mode); | 
| 911       __ tst(r0, Operand(kSmiTagMask)); | 921       __ tst(r0, Operand(kSmiTagMask)); | 
| 912       deferred->enter()->Branch(ne); | 922       deferred->Branch(ne); | 
| 913       switch (op) { | 923       switch (op) { | 
| 914         case Token::BIT_OR:  __ orr(r0, r0, Operand(value)); break; | 924         case Token::BIT_OR:  __ orr(r0, r0, Operand(value)); break; | 
| 915         case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break; | 925         case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break; | 
| 916         case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break; | 926         case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break; | 
| 917         default: UNREACHABLE(); | 927         default: UNREACHABLE(); | 
| 918       } | 928       } | 
| 919       deferred->BindExit(); | 929       deferred->BindExit(); | 
| 920       break; | 930       break; | 
| 921     } | 931     } | 
| 922 | 932 | 
| 923     case Token::SHL: | 933     case Token::SHL: | 
| 924     case Token::SHR: | 934     case Token::SHR: | 
| 925     case Token::SAR: { | 935     case Token::SAR: { | 
| 926       if (reversed) { | 936       if (reversed) { | 
| 927         __ mov(ip, Operand(value)); | 937         __ mov(ip, Operand(value)); | 
| 928         frame_->EmitPush(ip); | 938         frame_->EmitPush(ip); | 
| 929         frame_->EmitPush(r0); | 939         frame_->EmitPush(r0); | 
| 930         GenericBinaryOperation(op, mode); | 940         GenericBinaryOperation(op, mode); | 
| 931 | 941 | 
| 932       } else { | 942       } else { | 
| 933         int shift_value = int_value & 0x1f;  // least significant 5 bits | 943         int shift_value = int_value & 0x1f;  // least significant 5 bits | 
| 934         DeferredCode* deferred = | 944         DeferredCode* deferred = | 
| 935           new DeferredInlineSmiOperation(op, shift_value, false, mode); | 945           new DeferredInlineSmiOperation(op, shift_value, false, mode); | 
| 936         __ tst(r0, Operand(kSmiTagMask)); | 946         __ tst(r0, Operand(kSmiTagMask)); | 
| 937         deferred->enter()->Branch(ne); | 947         deferred->Branch(ne); | 
| 938         __ mov(r2, Operand(r0, ASR, kSmiTagSize));  // remove tags | 948         __ mov(r2, Operand(r0, ASR, kSmiTagSize));  // remove tags | 
| 939         switch (op) { | 949         switch (op) { | 
| 940           case Token::SHL: { | 950           case Token::SHL: { | 
| 941             __ mov(r2, Operand(r2, LSL, shift_value)); | 951             __ mov(r2, Operand(r2, LSL, shift_value)); | 
| 942             // check that the *unsigned* result fits in a smi | 952             // check that the *unsigned* result fits in a smi | 
| 943             __ add(r3, r2, Operand(0x40000000), SetCC); | 953             __ add(r3, r2, Operand(0x40000000), SetCC); | 
| 944             deferred->enter()->Branch(mi); | 954             deferred->Branch(mi); | 
| 945             break; | 955             break; | 
| 946           } | 956           } | 
| 947           case Token::SHR: { | 957           case Token::SHR: { | 
| 948             // LSR by immediate 0 means shifting 32 bits. | 958             // LSR by immediate 0 means shifting 32 bits. | 
| 949             if (shift_value != 0) { | 959             if (shift_value != 0) { | 
| 950               __ mov(r2, Operand(r2, LSR, shift_value)); | 960               __ mov(r2, Operand(r2, LSR, shift_value)); | 
| 951             } | 961             } | 
| 952             // check that the *unsigned* result fits in a smi | 962             // check that the *unsigned* result fits in a smi | 
| 953             // neither of the two high-order bits can be set: | 963             // neither of the two high-order bits can be set: | 
| 954             // - 0x80000000: high bit would be lost when smi tagging | 964             // - 0x80000000: high bit would be lost when smi tagging | 
| 955             // - 0x40000000: this number would convert to negative when | 965             // - 0x40000000: this number would convert to negative when | 
| 956             // smi tagging these two cases can only happen with shifts | 966             // smi tagging these two cases can only happen with shifts | 
| 957             // by 0 or 1 when handed a valid smi | 967             // by 0 or 1 when handed a valid smi | 
| 958             __ and_(r3, r2, Operand(0xc0000000), SetCC); | 968             __ and_(r3, r2, Operand(0xc0000000), SetCC); | 
| 959             deferred->enter()->Branch(ne); | 969             deferred->Branch(ne); | 
| 960             break; | 970             break; | 
| 961           } | 971           } | 
| 962           case Token::SAR: { | 972           case Token::SAR: { | 
| 963             if (shift_value != 0) { | 973             if (shift_value != 0) { | 
| 964               // ASR by immediate 0 means shifting 32 bits. | 974               // ASR by immediate 0 means shifting 32 bits. | 
| 965               __ mov(r2, Operand(r2, ASR, shift_value)); | 975               __ mov(r2, Operand(r2, ASR, shift_value)); | 
| 966             } | 976             } | 
| 967             break; | 977             break; | 
| 968           } | 978           } | 
| 969           default: UNREACHABLE(); | 979           default: UNREACHABLE(); | 
| (...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2663     set_comment("[ DeferredObjectLiteral"); | 2673     set_comment("[ DeferredObjectLiteral"); | 
| 2664   } | 2674   } | 
| 2665 | 2675 | 
| 2666   virtual void Generate(); | 2676   virtual void Generate(); | 
| 2667 | 2677 | 
| 2668  private: | 2678  private: | 
| 2669   ObjectLiteral* node_; | 2679   ObjectLiteral* node_; | 
| 2670 }; | 2680 }; | 
| 2671 | 2681 | 
| 2672 | 2682 | 
| 2673 #undef __ |  | 
| 2674 #define __ ACCESS_MASM(masm) |  | 
| 2675 |  | 
| 2676 |  | 
| 2677 void DeferredObjectLiteral::Generate() { | 2683 void DeferredObjectLiteral::Generate() { | 
| 2678   MacroAssembler* masm = cgen()->masm(); |  | 
| 2679   // Argument is passed in r1. | 2684   // Argument is passed in r1. | 
| 2680   enter()->Bind(); |  | 
| 2681   VirtualFrame::SpilledScope spilled_scope; |  | 
| 2682 | 2685 | 
| 2683   // If the entry is undefined we call the runtime system to compute | 2686   // If the entry is undefined we call the runtime system to compute | 
| 2684   // the literal. | 2687   // the literal. | 
| 2685 |  | 
| 2686   VirtualFrame* frame = cgen()->frame(); |  | 
| 2687   // Literal array (0). | 2688   // Literal array (0). | 
| 2688   frame->EmitPush(r1); | 2689   __ push(r1); | 
| 2689   // Literal index (1). | 2690   // Literal index (1). | 
| 2690   __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); | 2691   __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); | 
| 2691   frame->EmitPush(r0); | 2692   __ push(r0); | 
| 2692   // Constant properties (2). | 2693   // Constant properties (2). | 
| 2693   __ mov(r0, Operand(node_->constant_properties())); | 2694   __ mov(r0, Operand(node_->constant_properties())); | 
| 2694   frame->EmitPush(r0); | 2695   __ push(r0); | 
| 2695   Result boilerplate = | 2696   __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); | 
| 2696       frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); | 2697   __ mov(r2, Operand(r0)); | 
| 2697   __ mov(r2, Operand(boilerplate.reg())); |  | 
| 2698   // Result is returned in r2. | 2698   // Result is returned in r2. | 
| 2699   exit_.Jump(); |  | 
| 2700 } | 2699 } | 
| 2701 | 2700 | 
| 2702 | 2701 | 
| 2703 #undef __ |  | 
| 2704 #define __ ACCESS_MASM(masm_) |  | 
| 2705 |  | 
| 2706 |  | 
| 2707 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | 2702 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | 
| 2708 #ifdef DEBUG | 2703 #ifdef DEBUG | 
| 2709   int original_height = frame_->height(); | 2704   int original_height = frame_->height(); | 
| 2710 #endif | 2705 #endif | 
| 2711   VirtualFrame::SpilledScope spilled_scope; | 2706   VirtualFrame::SpilledScope spilled_scope; | 
| 2712   Comment cmnt(masm_, "[ ObjectLiteral"); | 2707   Comment cmnt(masm_, "[ ObjectLiteral"); | 
| 2713 | 2708 | 
| 2714   DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node); | 2709   DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node); | 
| 2715 | 2710 | 
| 2716   // Retrieve the literal array and check the allocated entry. | 2711   // Retrieve the literal array and check the allocated entry. | 
| 2717 | 2712 | 
| 2718   // Load the function of this activation. | 2713   // Load the function of this activation. | 
| 2719   __ ldr(r1, frame_->Function()); | 2714   __ ldr(r1, frame_->Function()); | 
| 2720 | 2715 | 
| 2721   // Load the literals array of the function. | 2716   // Load the literals array of the function. | 
| 2722   __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); | 2717   __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); | 
| 2723 | 2718 | 
| 2724   // Load the literal at the ast saved index. | 2719   // Load the literal at the ast saved index. | 
| 2725   int literal_offset = | 2720   int literal_offset = | 
| 2726       FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 2721       FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 
| 2727   __ ldr(r2, FieldMemOperand(r1, literal_offset)); | 2722   __ ldr(r2, FieldMemOperand(r1, literal_offset)); | 
| 2728 | 2723 | 
| 2729   // Check whether we need to materialize the object literal boilerplate. | 2724   // Check whether we need to materialize the object literal boilerplate. | 
| 2730   // If so, jump to the deferred code. | 2725   // If so, jump to the deferred code. | 
| 2731   __ cmp(r2, Operand(Factory::undefined_value())); | 2726   __ cmp(r2, Operand(Factory::undefined_value())); | 
| 2732   deferred->enter()->Branch(eq); | 2727   deferred->Branch(eq); | 
| 2733   deferred->BindExit(); | 2728   deferred->BindExit(); | 
| 2734 | 2729 | 
| 2735   // Push the object literal boilerplate. | 2730   // Push the object literal boilerplate. | 
| 2736   frame_->EmitPush(r2); | 2731   frame_->EmitPush(r2); | 
| 2737 | 2732 | 
| 2738   // Clone the boilerplate object. | 2733   // Clone the boilerplate object. | 
| 2739   Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; | 2734   Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; | 
| 2740   if (node->depth() == 1) { | 2735   if (node->depth() == 1) { | 
| 2741     clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; | 2736     clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; | 
| 2742   } | 2737   } | 
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2800     set_comment("[ DeferredArrayLiteral"); | 2795     set_comment("[ DeferredArrayLiteral"); | 
| 2801   } | 2796   } | 
| 2802 | 2797 | 
| 2803   virtual void Generate(); | 2798   virtual void Generate(); | 
| 2804 | 2799 | 
| 2805  private: | 2800  private: | 
| 2806   ArrayLiteral* node_; | 2801   ArrayLiteral* node_; | 
| 2807 }; | 2802 }; | 
| 2808 | 2803 | 
| 2809 | 2804 | 
| 2810 #undef __ |  | 
| 2811 #define __ ACCESS_MASM(masm) |  | 
| 2812 |  | 
| 2813 |  | 
| 2814 void DeferredArrayLiteral::Generate() { | 2805 void DeferredArrayLiteral::Generate() { | 
| 2815   MacroAssembler* masm = cgen()->masm(); |  | 
| 2816   // Argument is passed in r1. | 2806   // Argument is passed in r1. | 
| 2817   enter()->Bind(); |  | 
| 2818   VirtualFrame::SpilledScope spilled_scope; |  | 
| 2819 | 2807 | 
| 2820   // If the entry is undefined we call the runtime system to computed | 2808   // If the entry is undefined we call the runtime system to computed | 
| 2821   // the literal. | 2809   // the literal. | 
| 2822 |  | 
| 2823   VirtualFrame* frame = cgen()->frame(); |  | 
| 2824   // Literal array (0). | 2810   // Literal array (0). | 
| 2825   frame->EmitPush(r1); | 2811   __ push(r1); | 
| 2826   // Literal index (1). | 2812   // Literal index (1). | 
| 2827   __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); | 2813   __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); | 
| 2828   frame->EmitPush(r0); | 2814   __ push(r0); | 
| 2829   // Constant properties (2). | 2815   // Constant properties (2). | 
| 2830   __ mov(r0, Operand(node_->literals())); | 2816   __ mov(r0, Operand(node_->literals())); | 
| 2831   frame->EmitPush(r0); | 2817   __ push(r0); | 
| 2832   Result boilerplate = | 2818   __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3); | 
| 2833       frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3); | 2819   __ mov(r2, Operand(r0)); | 
| 2834   __ mov(r2, Operand(boilerplate.reg())); |  | 
| 2835   // Result is returned in r2. | 2820   // Result is returned in r2. | 
| 2836   exit_.Jump(); |  | 
| 2837 } | 2821 } | 
| 2838 | 2822 | 
| 2839 | 2823 | 
| 2840 #undef __ |  | 
| 2841 #define __ ACCESS_MASM(masm_) |  | 
| 2842 |  | 
| 2843 |  | 
| 2844 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { | 2824 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { | 
| 2845 #ifdef DEBUG | 2825 #ifdef DEBUG | 
| 2846   int original_height = frame_->height(); | 2826   int original_height = frame_->height(); | 
| 2847 #endif | 2827 #endif | 
| 2848   VirtualFrame::SpilledScope spilled_scope; | 2828   VirtualFrame::SpilledScope spilled_scope; | 
| 2849   Comment cmnt(masm_, "[ ArrayLiteral"); | 2829   Comment cmnt(masm_, "[ ArrayLiteral"); | 
| 2850 | 2830 | 
| 2851   DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node); | 2831   DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node); | 
| 2852 | 2832 | 
| 2853   // Retrieve the literal array and check the allocated entry. | 2833   // Retrieve the literal array and check the allocated entry. | 
| 2854 | 2834 | 
| 2855   // Load the function of this activation. | 2835   // Load the function of this activation. | 
| 2856   __ ldr(r1, frame_->Function()); | 2836   __ ldr(r1, frame_->Function()); | 
| 2857 | 2837 | 
| 2858   // Load the literals array of the function. | 2838   // Load the literals array of the function. | 
| 2859   __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); | 2839   __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); | 
| 2860 | 2840 | 
| 2861   // Load the literal at the ast saved index. | 2841   // Load the literal at the ast saved index. | 
| 2862   int literal_offset = | 2842   int literal_offset = | 
| 2863       FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 2843       FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 
| 2864   __ ldr(r2, FieldMemOperand(r1, literal_offset)); | 2844   __ ldr(r2, FieldMemOperand(r1, literal_offset)); | 
| 2865 | 2845 | 
| 2866   // Check whether we need to materialize the object literal boilerplate. | 2846   // Check whether we need to materialize the object literal boilerplate. | 
| 2867   // If so, jump to the deferred code. | 2847   // If so, jump to the deferred code. | 
| 2868   __ cmp(r2, Operand(Factory::undefined_value())); | 2848   __ cmp(r2, Operand(Factory::undefined_value())); | 
| 2869   deferred->enter()->Branch(eq); | 2849   deferred->Branch(eq); | 
| 2870   deferred->BindExit(); | 2850   deferred->BindExit(); | 
| 2871 | 2851 | 
| 2872   // Push the object literal boilerplate. | 2852   // Push the object literal boilerplate. | 
| 2873   frame_->EmitPush(r2); | 2853   frame_->EmitPush(r2); | 
| 2874 | 2854 | 
| 2875   // Clone the boilerplate object. | 2855   // Clone the boilerplate object. | 
| 2876   Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; | 2856   Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate; | 
| 2877   if (node->depth() == 1) { | 2857   if (node->depth() == 1) { | 
| 2878     clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; | 2858     clone_function_id = Runtime::kCloneShallowLiteralBoilerplate; | 
| 2879   } | 2859   } | 
| (...skipping 2330 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5210   __ mov(r2, Operand(0)); | 5190   __ mov(r2, Operand(0)); | 
| 5211   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 5191   __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 
| 5212   __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 5192   __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 
| 5213           RelocInfo::CODE_TARGET); | 5193           RelocInfo::CODE_TARGET); | 
| 5214 } | 5194 } | 
| 5215 | 5195 | 
| 5216 | 5196 | 
| 5217 #undef __ | 5197 #undef __ | 
| 5218 | 5198 | 
| 5219 } }  // namespace v8::internal | 5199 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|