| 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 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 UNREACHABLE(); | 778 UNREACHABLE(); |
| 779 break; | 779 break; |
| 780 } | 780 } |
| 781 | 781 |
| 782 GenericBinaryOpStub igostub(op_); | 782 GenericBinaryOpStub igostub(op_); |
| 783 Result arg0 = generator()->allocator()->Allocate(r0); | 783 Result arg0 = generator()->allocator()->Allocate(r0); |
| 784 ASSERT(arg0.is_valid()); | 784 ASSERT(arg0.is_valid()); |
| 785 Result arg1 = generator()->allocator()->Allocate(r1); | 785 Result arg1 = generator()->allocator()->Allocate(r1); |
| 786 ASSERT(arg1.is_valid()); | 786 ASSERT(arg1.is_valid()); |
| 787 generator()->frame()->CallStub(&igostub, &arg0, &arg1, 0); | 787 generator()->frame()->CallStub(&igostub, &arg0, &arg1, 0); |
| 788 exit()->Jump(); | 788 exit_.Jump(); |
| 789 } | 789 } |
| 790 | 790 |
| 791 | 791 |
| 792 void CodeGenerator::SmiOperation(Token::Value op, | 792 void CodeGenerator::SmiOperation(Token::Value op, |
| 793 Handle<Object> value, | 793 Handle<Object> value, |
| 794 bool reversed) { | 794 bool reversed) { |
| 795 VirtualFrame::SpilledScope spilled_scope(this); | 795 VirtualFrame::SpilledScope spilled_scope(this); |
| 796 // NOTE: This is an attempt to inline (a bit) more of the code for | 796 // NOTE: This is an attempt to inline (a bit) more of the code for |
| 797 // some possible smi operations (like + and -) when (at least) one | 797 // some possible smi operations (like + and -) when (at least) one |
| 798 // of the operands is a literal smi. With this optimization, the | 798 // of the operands is a literal smi. With this optimization, the |
| (...skipping 10 matching lines...) Expand all Loading... |
| 809 | 809 |
| 810 switch (op) { | 810 switch (op) { |
| 811 case Token::ADD: { | 811 case Token::ADD: { |
| 812 DeferredCode* deferred = | 812 DeferredCode* deferred = |
| 813 new DeferredInlineSmiOperation(this, op, int_value, reversed); | 813 new DeferredInlineSmiOperation(this, op, int_value, reversed); |
| 814 | 814 |
| 815 __ add(r0, r0, Operand(value), SetCC); | 815 __ add(r0, r0, Operand(value), SetCC); |
| 816 deferred->enter()->Branch(vs); | 816 deferred->enter()->Branch(vs); |
| 817 __ tst(r0, Operand(kSmiTagMask)); | 817 __ tst(r0, Operand(kSmiTagMask)); |
| 818 deferred->enter()->Branch(ne); | 818 deferred->enter()->Branch(ne); |
| 819 deferred->exit()->Bind(); | 819 deferred->BindExit(); |
| 820 break; | 820 break; |
| 821 } | 821 } |
| 822 | 822 |
| 823 case Token::SUB: { | 823 case Token::SUB: { |
| 824 DeferredCode* deferred = | 824 DeferredCode* deferred = |
| 825 new DeferredInlineSmiOperation(this, op, int_value, reversed); | 825 new DeferredInlineSmiOperation(this, op, int_value, reversed); |
| 826 | 826 |
| 827 if (!reversed) { | 827 if (!reversed) { |
| 828 __ sub(r0, r0, Operand(value), SetCC); | 828 __ sub(r0, r0, Operand(value), SetCC); |
| 829 } else { | 829 } else { |
| 830 __ rsb(r0, r0, Operand(value), SetCC); | 830 __ rsb(r0, r0, Operand(value), SetCC); |
| 831 } | 831 } |
| 832 deferred->enter()->Branch(vs); | 832 deferred->enter()->Branch(vs); |
| 833 __ tst(r0, Operand(kSmiTagMask)); | 833 __ tst(r0, Operand(kSmiTagMask)); |
| 834 deferred->enter()->Branch(ne); | 834 deferred->enter()->Branch(ne); |
| 835 deferred->exit()->Bind(); | 835 deferred->BindExit(); |
| 836 break; | 836 break; |
| 837 } | 837 } |
| 838 | 838 |
| 839 case Token::BIT_OR: | 839 case Token::BIT_OR: |
| 840 case Token::BIT_XOR: | 840 case Token::BIT_XOR: |
| 841 case Token::BIT_AND: { | 841 case Token::BIT_AND: { |
| 842 DeferredCode* deferred = | 842 DeferredCode* deferred = |
| 843 new DeferredInlineSmiOperation(this, op, int_value, reversed); | 843 new DeferredInlineSmiOperation(this, op, int_value, reversed); |
| 844 __ tst(r0, Operand(kSmiTagMask)); | 844 __ tst(r0, Operand(kSmiTagMask)); |
| 845 deferred->enter()->Branch(ne); | 845 deferred->enter()->Branch(ne); |
| 846 switch (op) { | 846 switch (op) { |
| 847 case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break; | 847 case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break; |
| 848 case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break; | 848 case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break; |
| 849 case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break; | 849 case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break; |
| 850 default: UNREACHABLE(); | 850 default: UNREACHABLE(); |
| 851 } | 851 } |
| 852 deferred->exit()->Bind(); | 852 deferred->BindExit(); |
| 853 break; | 853 break; |
| 854 } | 854 } |
| 855 | 855 |
| 856 case Token::SHL: | 856 case Token::SHL: |
| 857 case Token::SHR: | 857 case Token::SHR: |
| 858 case Token::SAR: { | 858 case Token::SAR: { |
| 859 if (reversed) { | 859 if (reversed) { |
| 860 __ mov(ip, Operand(value)); | 860 __ mov(ip, Operand(value)); |
| 861 frame_->EmitPush(ip); | 861 frame_->EmitPush(ip); |
| 862 frame_->EmitPush(r0); | 862 frame_->EmitPush(r0); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 case Token::SAR: { | 895 case Token::SAR: { |
| 896 if (shift_value != 0) { | 896 if (shift_value != 0) { |
| 897 // ASR by immediate 0 means shifting 32 bits. | 897 // ASR by immediate 0 means shifting 32 bits. |
| 898 __ mov(r2, Operand(r2, ASR, shift_value)); | 898 __ mov(r2, Operand(r2, ASR, shift_value)); |
| 899 } | 899 } |
| 900 break; | 900 break; |
| 901 } | 901 } |
| 902 default: UNREACHABLE(); | 902 default: UNREACHABLE(); |
| 903 } | 903 } |
| 904 __ mov(r0, Operand(r2, LSL, kSmiTagSize)); | 904 __ mov(r0, Operand(r2, LSL, kSmiTagSize)); |
| 905 deferred->exit()->Bind(); | 905 deferred->BindExit(); |
| 906 } | 906 } |
| 907 break; | 907 break; |
| 908 } | 908 } |
| 909 | 909 |
| 910 default: | 910 default: |
| 911 if (!reversed) { | 911 if (!reversed) { |
| 912 frame_->EmitPush(r0); | 912 frame_->EmitPush(r0); |
| 913 __ mov(r0, Operand(value)); | 913 __ mov(r0, Operand(value)); |
| 914 frame_->EmitPush(r0); | 914 frame_->EmitPush(r0); |
| 915 } else { | 915 } else { |
| (...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2338 // Literal index (1). | 2338 // Literal index (1). |
| 2339 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); | 2339 __ mov(r0, Operand(Smi::FromInt(node_->literal_index()))); |
| 2340 frame->EmitPush(r0); | 2340 frame->EmitPush(r0); |
| 2341 // Constant properties (2). | 2341 // Constant properties (2). |
| 2342 __ mov(r0, Operand(node_->constant_properties())); | 2342 __ mov(r0, Operand(node_->constant_properties())); |
| 2343 frame->EmitPush(r0); | 2343 frame->EmitPush(r0); |
| 2344 Result boilerplate = | 2344 Result boilerplate = |
| 2345 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); | 2345 frame->CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); |
| 2346 __ mov(r2, Operand(boilerplate.reg())); | 2346 __ mov(r2, Operand(boilerplate.reg())); |
| 2347 // Result is returned in r2. | 2347 // Result is returned in r2. |
| 2348 exit()->Jump(); | 2348 exit_.Jump(); |
| 2349 } | 2349 } |
| 2350 | 2350 |
| 2351 | 2351 |
| 2352 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { | 2352 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { |
| 2353 VirtualFrame::SpilledScope spilled_scope(this); | 2353 VirtualFrame::SpilledScope spilled_scope(this); |
| 2354 Comment cmnt(masm_, "[ ObjectLiteral"); | 2354 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 2355 | 2355 |
| 2356 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node); | 2356 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(this, node); |
| 2357 | 2357 |
| 2358 // Retrieve the literal array and check the allocated entry. | 2358 // Retrieve the literal array and check the allocated entry. |
| 2359 | 2359 |
| 2360 // Load the function of this activation. | 2360 // Load the function of this activation. |
| 2361 __ ldr(r1, frame_->Function()); | 2361 __ ldr(r1, frame_->Function()); |
| 2362 | 2362 |
| 2363 // Load the literals array of the function. | 2363 // Load the literals array of the function. |
| 2364 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); | 2364 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); |
| 2365 | 2365 |
| 2366 // Load the literal at the ast saved index. | 2366 // Load the literal at the ast saved index. |
| 2367 int literal_offset = | 2367 int literal_offset = |
| 2368 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; | 2368 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; |
| 2369 __ ldr(r2, FieldMemOperand(r1, literal_offset)); | 2369 __ ldr(r2, FieldMemOperand(r1, literal_offset)); |
| 2370 | 2370 |
| 2371 // Check whether we need to materialize the object literal boilerplate. | 2371 // Check whether we need to materialize the object literal boilerplate. |
| 2372 // If so, jump to the deferred code. | 2372 // If so, jump to the deferred code. |
| 2373 __ cmp(r2, Operand(Factory::undefined_value())); | 2373 __ cmp(r2, Operand(Factory::undefined_value())); |
| 2374 deferred->enter()->Branch(eq); | 2374 deferred->enter()->Branch(eq); |
| 2375 deferred->exit()->Bind(); | 2375 deferred->BindExit(); |
| 2376 | 2376 |
| 2377 // Push the object literal boilerplate. | 2377 // Push the object literal boilerplate. |
| 2378 frame_->EmitPush(r2); | 2378 frame_->EmitPush(r2); |
| 2379 | 2379 |
| 2380 // Clone the boilerplate object. | 2380 // Clone the boilerplate object. |
| 2381 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1); | 2381 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1); |
| 2382 frame_->EmitPush(r0); // save the result | 2382 frame_->EmitPush(r0); // save the result |
| 2383 // r0: cloned object literal | 2383 // r0: cloned object literal |
| 2384 | 2384 |
| 2385 for (int i = 0; i < node->properties()->length(); i++) { | 2385 for (int i = 0; i < node->properties()->length(); i++) { |
| (...skipping 2322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4708 __ mov(r2, Operand(0)); | 4708 __ mov(r2, Operand(0)); |
| 4709 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 4709 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 4710 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 4710 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
| 4711 RelocInfo::CODE_TARGET); | 4711 RelocInfo::CODE_TARGET); |
| 4712 } | 4712 } |
| 4713 | 4713 |
| 4714 | 4714 |
| 4715 #undef __ | 4715 #undef __ |
| 4716 | 4716 |
| 4717 } } // namespace v8::internal | 4717 } } // namespace v8::internal |
| OLD | NEW |