Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(898)

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 15085026: ARM: Smi refactoring and improvements. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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, &not_found); 3785 __ b(ne, &not_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(&not_found); 3790 __ bind(&not_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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/disasm-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | src/arm/macro-assembler-arm.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698