| 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 1180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1191 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1191 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 1192 __ bind(&loop); | 1192 __ bind(&loop); |
| 1193 // Load the current count to r0, load the length to r1. | 1193 // Load the current count to r0, load the length to r1. |
| 1194 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize)); | 1194 __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize)); |
| 1195 __ cmp(r0, r1); // Compare to the array length. | 1195 __ cmp(r0, r1); // Compare to the array length. |
| 1196 __ b(hs, loop_statement.break_label()); | 1196 __ b(hs, loop_statement.break_label()); |
| 1197 | 1197 |
| 1198 // Get the current entry of the array into register r3. | 1198 // Get the current entry of the array into register r3. |
| 1199 __ ldr(r2, MemOperand(sp, 2 * kPointerSize)); | 1199 __ ldr(r2, MemOperand(sp, 2 * kPointerSize)); |
| 1200 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1200 __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1201 __ ldr(r3, MemOperand(r2, r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1201 __ ldr(r3, MemOperand::PointerAddressFromSmiKey(r2, r0)); |
| 1202 | 1202 |
| 1203 // Get the expected map from the stack or a smi in the | 1203 // Get the expected map from the stack or a smi in the |
| 1204 // permanent slow case into register r2. | 1204 // permanent slow case into register r2. |
| 1205 __ ldr(r2, MemOperand(sp, 3 * kPointerSize)); | 1205 __ ldr(r2, MemOperand(sp, 3 * kPointerSize)); |
| 1206 | 1206 |
| 1207 // Check if the expected map still matches that of the enumerable. | 1207 // Check if the expected map still matches that of the enumerable. |
| 1208 // If not, we may have to filter the key. | 1208 // If not, we may have to filter the key. |
| 1209 Label update_each; | 1209 Label update_each; |
| 1210 __ ldr(r1, MemOperand(sp, 4 * kPointerSize)); | 1210 __ ldr(r1, MemOperand(sp, 4 * kPointerSize)); |
| 1211 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1211 __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset)); |
| (...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2256 expr->BinaryOperationFeedbackId()); | 2256 expr->BinaryOperationFeedbackId()); |
| 2257 patch_site.EmitPatchInfo(); | 2257 patch_site.EmitPatchInfo(); |
| 2258 __ jmp(&done); | 2258 __ jmp(&done); |
| 2259 | 2259 |
| 2260 __ bind(&smi_case); | 2260 __ bind(&smi_case); |
| 2261 // Smi case. This code works the same way as the smi-smi case in the type | 2261 // Smi case. This code works the same way as the smi-smi case in the type |
| 2262 // recording binary operation stub, see | 2262 // recording binary operation stub, see |
| 2263 // BinaryOpStub::GenerateSmiSmiOperation for comments. | 2263 // BinaryOpStub::GenerateSmiSmiOperation for comments. |
| 2264 switch (op) { | 2264 switch (op) { |
| 2265 case Token::SAR: | 2265 case Token::SAR: |
| 2266 __ b(&stub_call); | |
| 2267 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2266 __ GetLeastBitsFromSmi(scratch1, right, 5); |
| 2268 __ mov(right, Operand(left, ASR, scratch1)); | 2267 __ mov(right, Operand(left, ASR, scratch1)); |
| 2269 __ bic(right, right, Operand(kSmiTagMask)); | 2268 __ bic(right, right, Operand(kSmiTagMask)); |
| 2270 break; | 2269 break; |
| 2271 case Token::SHL: { | 2270 case Token::SHL: { |
| 2272 __ b(&stub_call); | |
| 2273 __ SmiUntag(scratch1, left); | 2271 __ SmiUntag(scratch1, left); |
| 2274 __ GetLeastBitsFromSmi(scratch2, right, 5); | 2272 __ GetLeastBitsFromSmi(scratch2, right, 5); |
| 2275 __ mov(scratch1, Operand(scratch1, LSL, scratch2)); | 2273 __ mov(scratch1, Operand(scratch1, LSL, scratch2)); |
| 2276 __ add(scratch2, scratch1, Operand(0x40000000), SetCC); | 2274 __ TrySmiTag(right, scratch1, &stub_call); |
| 2277 __ b(mi, &stub_call); | |
| 2278 __ SmiTag(right, scratch1); | |
| 2279 break; | 2275 break; |
| 2280 } | 2276 } |
| 2281 case Token::SHR: { | 2277 case Token::SHR: { |
| 2282 __ b(&stub_call); | |
| 2283 __ SmiUntag(scratch1, left); | 2278 __ SmiUntag(scratch1, left); |
| 2284 __ GetLeastBitsFromSmi(scratch2, right, 5); | 2279 __ GetLeastBitsFromSmi(scratch2, right, 5); |
| 2285 __ mov(scratch1, Operand(scratch1, LSR, scratch2)); | 2280 __ mov(scratch1, Operand(scratch1, LSR, scratch2)); |
| 2286 __ tst(scratch1, Operand(0xc0000000)); | 2281 __ tst(scratch1, Operand(0xc0000000)); |
| 2287 __ b(ne, &stub_call); | 2282 __ b(ne, &stub_call); |
| 2288 __ SmiTag(right, scratch1); | 2283 __ SmiTag(right, scratch1); |
| 2289 break; | 2284 break; |
| 2290 } | 2285 } |
| 2291 case Token::ADD: | 2286 case Token::ADD: |
| 2292 __ add(scratch1, left, Operand(right), SetCC); | 2287 __ add(scratch1, left, Operand(right), SetCC); |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2851 VisitForAccumulatorValue(args->at(0)); | 2846 VisitForAccumulatorValue(args->at(0)); |
| 2852 | 2847 |
| 2853 Label materialize_true, materialize_false; | 2848 Label materialize_true, materialize_false; |
| 2854 Label* if_true = NULL; | 2849 Label* if_true = NULL; |
| 2855 Label* if_false = NULL; | 2850 Label* if_false = NULL; |
| 2856 Label* fall_through = NULL; | 2851 Label* fall_through = NULL; |
| 2857 context()->PrepareTest(&materialize_true, &materialize_false, | 2852 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2858 &if_true, &if_false, &fall_through); | 2853 &if_true, &if_false, &fall_through); |
| 2859 | 2854 |
| 2860 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 2855 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2861 __ tst(r0, Operand(kSmiTagMask)); | 2856 __ SmiTst(r0); |
| 2862 Split(eq, if_true, if_false, fall_through); | 2857 Split(eq, if_true, if_false, fall_through); |
| 2863 | 2858 |
| 2864 context()->Plug(if_true, if_false); | 2859 context()->Plug(if_true, if_false); |
| 2865 } | 2860 } |
| 2866 | 2861 |
| 2867 | 2862 |
| 2868 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { | 2863 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { |
| 2869 ZoneList<Expression*>* args = expr->arguments(); | 2864 ZoneList<Expression*>* args = expr->arguments(); |
| 2870 ASSERT(args->length() == 1); | 2865 ASSERT(args->length() == 1); |
| 2871 | 2866 |
| 2872 VisitForAccumulatorValue(args->at(0)); | 2867 VisitForAccumulatorValue(args->at(0)); |
| 2873 | 2868 |
| 2874 Label materialize_true, materialize_false; | 2869 Label materialize_true, materialize_false; |
| 2875 Label* if_true = NULL; | 2870 Label* if_true = NULL; |
| 2876 Label* if_false = NULL; | 2871 Label* if_false = NULL; |
| 2877 Label* fall_through = NULL; | 2872 Label* fall_through = NULL; |
| 2878 context()->PrepareTest(&materialize_true, &materialize_false, | 2873 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2879 &if_true, &if_false, &fall_through); | 2874 &if_true, &if_false, &fall_through); |
| 2880 | 2875 |
| 2881 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 2876 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2882 __ tst(r0, Operand(kSmiTagMask | 0x80000000)); | 2877 __ NonNegativeSmiTst(r0); |
| 2883 Split(eq, if_true, if_false, fall_through); | 2878 Split(eq, if_true, if_false, fall_through); |
| 2884 | 2879 |
| 2885 context()->Plug(if_true, if_false); | 2880 context()->Plug(if_true, if_false); |
| 2886 } | 2881 } |
| 2887 | 2882 |
| 2888 | 2883 |
| 2889 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { | 2884 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { |
| 2890 ZoneList<Expression*>* args = expr->arguments(); | 2885 ZoneList<Expression*>* args = expr->arguments(); |
| 2891 ASSERT(args->length() == 1); | 2886 ASSERT(args->length() == 1); |
| 2892 | 2887 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2999 Label entry, loop, done; | 2994 Label entry, loop, done; |
| 3000 | 2995 |
| 3001 // Skip loop if no descriptors are valid. | 2996 // Skip loop if no descriptors are valid. |
| 3002 __ NumberOfOwnDescriptors(r3, r1); | 2997 __ NumberOfOwnDescriptors(r3, r1); |
| 3003 __ cmp(r3, Operand::Zero()); | 2998 __ cmp(r3, Operand::Zero()); |
| 3004 __ b(eq, &done); | 2999 __ b(eq, &done); |
| 3005 | 3000 |
| 3006 __ LoadInstanceDescriptors(r1, r4); | 3001 __ LoadInstanceDescriptors(r1, r4); |
| 3007 // r4: descriptor array. | 3002 // r4: descriptor array. |
| 3008 // r3: valid entries in the descriptor array. | 3003 // r3: valid entries in the descriptor array. |
| 3009 STATIC_ASSERT(kSmiTag == 0); | |
| 3010 STATIC_ASSERT(kSmiTagSize == 1); | |
| 3011 STATIC_ASSERT(kPointerSize == 4); | |
| 3012 __ mov(ip, Operand(DescriptorArray::kDescriptorSize)); | 3004 __ mov(ip, Operand(DescriptorArray::kDescriptorSize)); |
| 3013 __ mul(r3, r3, ip); | 3005 __ mul(r3, r3, ip); |
| 3014 // Calculate location of the first key name. | 3006 // Calculate location of the first key name. |
| 3015 __ add(r4, r4, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag)); | 3007 __ add(r4, r4, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag)); |
| 3016 // Calculate the end of the descriptor array. | 3008 // Calculate the end of the descriptor array. |
| 3017 __ mov(r2, r4); | 3009 __ mov(r2, r4); |
| 3018 __ add(r2, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize)); | 3010 __ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3)); |
| 3019 | 3011 |
| 3020 // Loop through all the keys in the descriptor array. If one of these is the | 3012 // Loop through all the keys in the descriptor array. If one of these is the |
| 3021 // string "valueOf" the result is false. | 3013 // string "valueOf" the result is false. |
| 3022 // The use of ip to store the valueOf string assumes that it is not otherwise | 3014 // The use of ip to store the valueOf string assumes that it is not otherwise |
| 3023 // used in the loop below. | 3015 // used in the loop below. |
| 3024 __ mov(ip, Operand(FACTORY->value_of_string())); | 3016 __ mov(ip, Operand(FACTORY->value_of_string())); |
| 3025 __ jmp(&entry); | 3017 __ jmp(&entry); |
| 3026 __ bind(&loop); | 3018 __ bind(&loop); |
| 3027 __ ldr(r3, MemOperand(r4, 0)); | 3019 __ ldr(r3, MemOperand(r4, 0)); |
| 3028 __ cmp(r3, ip); | 3020 __ cmp(r3, ip); |
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3776 Register cache = r1; | 3768 Register cache = r1; |
| 3777 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); | 3769 __ ldr(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); |
| 3778 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset)); | 3770 __ ldr(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset)); |
| 3779 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); | 3771 __ ldr(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); |
| 3780 __ ldr(cache, | 3772 __ ldr(cache, |
| 3781 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); | 3773 FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); |
| 3782 | 3774 |
| 3783 | 3775 |
| 3784 Label done, not_found; | 3776 Label done, not_found; |
| 3785 // tmp now holds finger offset as a smi. | 3777 // tmp now holds finger offset as a smi. |
| 3786 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | |
| 3787 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset)); | 3778 __ ldr(r2, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset)); |
| 3788 // r2 now holds finger offset as a smi. | 3779 // r2 now holds finger offset as a smi. |
| 3789 __ add(r3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 3780 __ add(r3, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 3790 // r3 now points to the start of fixed array elements. | 3781 // r3 now points to the start of fixed array elements. |
| 3791 __ ldr(r2, MemOperand(r3, r2, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex)); | 3782 __ ldr(r2, MemOperand::PointerAddressFromSmiKey(r3, r2, PreIndex)); |
| 3792 // Note side effect of PreIndex: r3 now points to the key of the pair. | 3783 // Note side effect of PreIndex: r3 now points to the key of the pair. |
| 3793 __ cmp(key, r2); | 3784 __ cmp(key, r2); |
| 3794 __ b(ne, ¬_found); | 3785 __ b(ne, ¬_found); |
| 3795 | 3786 |
| 3796 __ ldr(r0, MemOperand(r3, kPointerSize)); | 3787 __ ldr(r0, MemOperand(r3, kPointerSize)); |
| 3797 __ b(&done); | 3788 __ b(&done); |
| 3798 | 3789 |
| 3799 __ bind(¬_found); | 3790 __ bind(¬_found); |
| 3800 // Call runtime to perform the lookup. | 3791 // Call runtime to perform the lookup. |
| 3801 __ Push(cache, key); | 3792 __ Push(cache, key); |
| (...skipping 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4744 | 4735 |
| 4745 // ---------------------------------------------------------------------------- | 4736 // ---------------------------------------------------------------------------- |
| 4746 // Non-local control flow support. | 4737 // Non-local control flow support. |
| 4747 | 4738 |
| 4748 void FullCodeGenerator::EnterFinallyBlock() { | 4739 void FullCodeGenerator::EnterFinallyBlock() { |
| 4749 ASSERT(!result_register().is(r1)); | 4740 ASSERT(!result_register().is(r1)); |
| 4750 // Store result register while executing finally block. | 4741 // Store result register while executing finally block. |
| 4751 __ push(result_register()); | 4742 __ push(result_register()); |
| 4752 // Cook return address in link register to stack (smi encoded Code* delta) | 4743 // Cook return address in link register to stack (smi encoded Code* delta) |
| 4753 __ sub(r1, lr, Operand(masm_->CodeObject())); | 4744 __ sub(r1, lr, Operand(masm_->CodeObject())); |
| 4754 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 4745 __ SmiTag(r1); |
| 4755 STATIC_ASSERT(kSmiTag == 0); | |
| 4756 __ add(r1, r1, Operand(r1)); // Convert to smi. | |
| 4757 | 4746 |
| 4758 // Store result register while executing finally block. | 4747 // Store result register while executing finally block. |
| 4759 __ push(r1); | 4748 __ push(r1); |
| 4760 | 4749 |
| 4761 // Store pending message while executing finally block. | 4750 // Store pending message while executing finally block. |
| 4762 ExternalReference pending_message_obj = | 4751 ExternalReference pending_message_obj = |
| 4763 ExternalReference::address_of_pending_message_obj(isolate()); | 4752 ExternalReference::address_of_pending_message_obj(isolate()); |
| 4764 __ mov(ip, Operand(pending_message_obj)); | 4753 __ mov(ip, Operand(pending_message_obj)); |
| 4765 __ ldr(r1, MemOperand(ip)); | 4754 __ ldr(r1, MemOperand(ip)); |
| 4766 __ push(r1); | 4755 __ push(r1); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4800 ExternalReference pending_message_obj = | 4789 ExternalReference pending_message_obj = |
| 4801 ExternalReference::address_of_pending_message_obj(isolate()); | 4790 ExternalReference::address_of_pending_message_obj(isolate()); |
| 4802 __ mov(ip, Operand(pending_message_obj)); | 4791 __ mov(ip, Operand(pending_message_obj)); |
| 4803 __ str(r1, MemOperand(ip)); | 4792 __ str(r1, MemOperand(ip)); |
| 4804 | 4793 |
| 4805 // Restore result register from stack. | 4794 // Restore result register from stack. |
| 4806 __ pop(r1); | 4795 __ pop(r1); |
| 4807 | 4796 |
| 4808 // Uncook return address and return. | 4797 // Uncook return address and return. |
| 4809 __ pop(result_register()); | 4798 __ pop(result_register()); |
| 4810 ASSERT_EQ(1, kSmiTagSize + kSmiShiftSize); | 4799 __ SmiUntag(r1); |
| 4811 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | |
| 4812 __ add(pc, r1, Operand(masm_->CodeObject())); | 4800 __ add(pc, r1, Operand(masm_->CodeObject())); |
| 4813 } | 4801 } |
| 4814 | 4802 |
| 4815 | 4803 |
| 4816 #undef __ | 4804 #undef __ |
| 4817 | 4805 |
| 4818 #define __ ACCESS_MASM(masm()) | 4806 #define __ ACCESS_MASM(masm()) |
| 4819 | 4807 |
| 4820 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( | 4808 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( |
| 4821 int* stack_depth, | 4809 int* stack_depth, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4839 *context_length = 0; | 4827 *context_length = 0; |
| 4840 return previous_; | 4828 return previous_; |
| 4841 } | 4829 } |
| 4842 | 4830 |
| 4843 | 4831 |
| 4844 #undef __ | 4832 #undef __ |
| 4845 | 4833 |
| 4846 } } // namespace v8::internal | 4834 } } // namespace v8::internal |
| 4847 | 4835 |
| 4848 #endif // V8_TARGET_ARCH_ARM | 4836 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |