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 |