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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 9227007: Version 3.8.6 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 11 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
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/cpu-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 __ AllocateInNewSpace(FixedArray::SizeFor(length), 149 __ AllocateInNewSpace(FixedArray::SizeFor(length),
150 r0, 150 r0,
151 r1, 151 r1,
152 r2, 152 r2,
153 &gc, 153 &gc,
154 TAG_OBJECT); 154 TAG_OBJECT);
155 155
156 // Load the function from the stack. 156 // Load the function from the stack.
157 __ ldr(r3, MemOperand(sp, 0)); 157 __ ldr(r3, MemOperand(sp, 0));
158 158
159 // Setup the object header. 159 // Set up the object header.
160 __ LoadRoot(r2, Heap::kFunctionContextMapRootIndex); 160 __ LoadRoot(r2, Heap::kFunctionContextMapRootIndex);
161 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 161 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
162 __ mov(r2, Operand(Smi::FromInt(length))); 162 __ mov(r2, Operand(Smi::FromInt(length)));
163 __ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset)); 163 __ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
164 164
165 // Setup the fixed slots. 165 // Set up the fixed slots.
166 __ mov(r1, Operand(Smi::FromInt(0))); 166 __ mov(r1, Operand(Smi::FromInt(0)));
167 __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX))); 167 __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX)));
168 __ str(cp, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX))); 168 __ str(cp, MemOperand(r0, Context::SlotOffset(Context::PREVIOUS_INDEX)));
169 __ str(r1, MemOperand(r0, Context::SlotOffset(Context::EXTENSION_INDEX))); 169 __ str(r1, MemOperand(r0, Context::SlotOffset(Context::EXTENSION_INDEX)));
170 170
171 // Copy the global object from the previous context. 171 // Copy the global object from the previous context.
172 __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); 172 __ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
173 __ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX))); 173 __ str(r1, MemOperand(r0, Context::SlotOffset(Context::GLOBAL_INDEX)));
174 174
175 // Initialize the rest of the slots to undefined. 175 // Initialize the rest of the slots to undefined.
(...skipping 24 matching lines...) Expand all
200 int length = slots_ + Context::MIN_CONTEXT_SLOTS; 200 int length = slots_ + Context::MIN_CONTEXT_SLOTS;
201 __ AllocateInNewSpace(FixedArray::SizeFor(length), 201 __ AllocateInNewSpace(FixedArray::SizeFor(length),
202 r0, r1, r2, &gc, TAG_OBJECT); 202 r0, r1, r2, &gc, TAG_OBJECT);
203 203
204 // Load the function from the stack. 204 // Load the function from the stack.
205 __ ldr(r3, MemOperand(sp, 0)); 205 __ ldr(r3, MemOperand(sp, 0));
206 206
207 // Load the serialized scope info from the stack. 207 // Load the serialized scope info from the stack.
208 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 208 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
209 209
210 // Setup the object header. 210 // Set up the object header.
211 __ LoadRoot(r2, Heap::kBlockContextMapRootIndex); 211 __ LoadRoot(r2, Heap::kBlockContextMapRootIndex);
212 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 212 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
213 __ mov(r2, Operand(Smi::FromInt(length))); 213 __ mov(r2, Operand(Smi::FromInt(length)));
214 __ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset)); 214 __ str(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
215 215
216 // If this block context is nested in the global context we get a smi 216 // If this block context is nested in the global context we get a smi
217 // sentinel instead of a function. The block context should get the 217 // sentinel instead of a function. The block context should get the
218 // canonical empty function of the global context as its closure which 218 // canonical empty function of the global context as its closure which
219 // we still have to look up. 219 // we still have to look up.
220 Label after_sentinel; 220 Label after_sentinel;
221 __ JumpIfNotSmi(r3, &after_sentinel); 221 __ JumpIfNotSmi(r3, &after_sentinel);
222 if (FLAG_debug_code) { 222 if (FLAG_debug_code) {
223 const char* message = "Expected 0 as a Smi sentinel"; 223 const char* message = "Expected 0 as a Smi sentinel";
224 __ cmp(r3, Operand::Zero()); 224 __ cmp(r3, Operand::Zero());
225 __ Assert(eq, message); 225 __ Assert(eq, message);
226 } 226 }
227 __ ldr(r3, GlobalObjectOperand()); 227 __ ldr(r3, GlobalObjectOperand());
228 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset)); 228 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset));
229 __ ldr(r3, ContextOperand(r3, Context::CLOSURE_INDEX)); 229 __ ldr(r3, ContextOperand(r3, Context::CLOSURE_INDEX));
230 __ bind(&after_sentinel); 230 __ bind(&after_sentinel);
231 231
232 // Setup the fixed slots. 232 // Set up the fixed slots.
233 __ str(r3, ContextOperand(r0, Context::CLOSURE_INDEX)); 233 __ str(r3, ContextOperand(r0, Context::CLOSURE_INDEX));
234 __ str(cp, ContextOperand(r0, Context::PREVIOUS_INDEX)); 234 __ str(cp, ContextOperand(r0, Context::PREVIOUS_INDEX));
235 __ str(r1, ContextOperand(r0, Context::EXTENSION_INDEX)); 235 __ str(r1, ContextOperand(r0, Context::EXTENSION_INDEX));
236 236
237 // Copy the global object from the previous context. 237 // Copy the global object from the previous context.
238 __ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX)); 238 __ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX));
239 __ str(r1, ContextOperand(r0, Context::GLOBAL_INDEX)); 239 __ str(r1, ContextOperand(r0, Context::GLOBAL_INDEX));
240 240
241 // Initialize the rest of the slots to the hole value. 241 // Initialize the rest of the slots to the hole value.
242 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex); 242 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 __ cmp(int_scratch, Operand::Zero()); 710 __ cmp(int_scratch, Operand::Zero());
711 __ mov(dst2, int_scratch); 711 __ mov(dst2, int_scratch);
712 __ mov(dst1, int_scratch); 712 __ mov(dst1, int_scratch);
713 __ b(eq, &done); 713 __ b(eq, &done);
714 714
715 // Preload the sign of the value. 715 // Preload the sign of the value.
716 __ and_(dst2, int_scratch, Operand(HeapNumber::kSignMask), SetCC); 716 __ and_(dst2, int_scratch, Operand(HeapNumber::kSignMask), SetCC);
717 // Get the absolute value of the object (as an unsigned integer). 717 // Get the absolute value of the object (as an unsigned integer).
718 __ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi); 718 __ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi);
719 719
720 // Get mantisssa[51:20]. 720 // Get mantissa[51:20].
721 721
722 // Get the position of the first set bit. 722 // Get the position of the first set bit.
723 __ CountLeadingZeros(dst1, int_scratch, scratch2); 723 __ CountLeadingZeros(dst1, int_scratch, scratch2);
724 __ rsb(dst1, dst1, Operand(31)); 724 __ rsb(dst1, dst1, Operand(31));
725 725
726 // Set the exponent. 726 // Set the exponent.
727 __ add(scratch2, dst1, Operand(HeapNumber::kExponentBias)); 727 __ add(scratch2, dst1, Operand(HeapNumber::kExponentBias));
728 __ Bfi(dst2, scratch2, scratch2, 728 __ Bfi(dst2, scratch2, scratch2,
729 HeapNumber::kExponentShift, HeapNumber::kExponentBits); 729 HeapNumber::kExponentShift, HeapNumber::kExponentBits);
730 730
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 __ cmp(tmp, Operand(30)); 944 __ cmp(tmp, Operand(30));
945 __ b(gt, not_int32); 945 __ b(gt, not_int32);
946 // - Bits [21:0] in the mantissa are not null. 946 // - Bits [21:0] in the mantissa are not null.
947 __ tst(src2, Operand(0x3fffff)); 947 __ tst(src2, Operand(0x3fffff));
948 __ b(ne, not_int32); 948 __ b(ne, not_int32);
949 949
950 // Otherwise the exponent needs to be big enough to shift left all the 950 // Otherwise the exponent needs to be big enough to shift left all the
951 // non zero bits left. So we need the (30 - exponent) last bits of the 951 // non zero bits left. So we need the (30 - exponent) last bits of the
952 // 31 higher bits of the mantissa to be null. 952 // 31 higher bits of the mantissa to be null.
953 // Because bits [21:0] are null, we can check instead that the 953 // Because bits [21:0] are null, we can check instead that the
954 // (32 - exponent) last bits of the 32 higher bits of the mantisssa are null. 954 // (32 - exponent) last bits of the 32 higher bits of the mantissa are null.
955 955
956 // Get the 32 higher bits of the mantissa in dst. 956 // Get the 32 higher bits of the mantissa in dst.
957 __ Ubfx(dst, 957 __ Ubfx(dst,
958 src2, 958 src2,
959 HeapNumber::kMantissaBitsInTopWord, 959 HeapNumber::kMantissaBitsInTopWord,
960 32 - HeapNumber::kMantissaBitsInTopWord); 960 32 - HeapNumber::kMantissaBitsInTopWord);
961 __ orr(dst, 961 __ orr(dst,
962 dst, 962 dst,
963 Operand(src1, LSL, HeapNumber::kNonMantissaBitsInTopWord)); 963 Operand(src1, LSL, HeapNumber::kNonMantissaBitsInTopWord));
964 964
(...skipping 2870 matching lines...) Expand 10 before | Expand all | Expand 10 after
3835 // builtin once. 3835 // builtin once.
3836 3836
3837 // Compute the argv pointer in a callee-saved register. 3837 // Compute the argv pointer in a callee-saved register.
3838 __ add(r6, sp, Operand(r0, LSL, kPointerSizeLog2)); 3838 __ add(r6, sp, Operand(r0, LSL, kPointerSizeLog2));
3839 __ sub(r6, r6, Operand(kPointerSize)); 3839 __ sub(r6, r6, Operand(kPointerSize));
3840 3840
3841 // Enter the exit frame that transitions from JavaScript to C++. 3841 // Enter the exit frame that transitions from JavaScript to C++.
3842 FrameScope scope(masm, StackFrame::MANUAL); 3842 FrameScope scope(masm, StackFrame::MANUAL);
3843 __ EnterExitFrame(save_doubles_); 3843 __ EnterExitFrame(save_doubles_);
3844 3844
3845 // Setup argc and the builtin function in callee-saved registers. 3845 // Set up argc and the builtin function in callee-saved registers.
3846 __ mov(r4, Operand(r0)); 3846 __ mov(r4, Operand(r0));
3847 __ mov(r5, Operand(r1)); 3847 __ mov(r5, Operand(r1));
3848 3848
3849 // r4: number of arguments (C callee-saved) 3849 // r4: number of arguments (C callee-saved)
3850 // r5: pointer to builtin function (C callee-saved) 3850 // r5: pointer to builtin function (C callee-saved)
3851 // r6: pointer to first argument (C callee-saved) 3851 // r6: pointer to first argument (C callee-saved)
3852 3852
3853 Label throw_normal_exception; 3853 Label throw_normal_exception;
3854 Label throw_termination_exception; 3854 Label throw_termination_exception;
3855 Label throw_out_of_memory_exception; 3855 Label throw_out_of_memory_exception;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3912 // Set up the reserved register for 0.0. 3912 // Set up the reserved register for 0.0.
3913 __ vmov(kDoubleRegZero, 0.0); 3913 __ vmov(kDoubleRegZero, 0.0);
3914 } 3914 }
3915 3915
3916 // Get address of argv, see stm above. 3916 // Get address of argv, see stm above.
3917 // r0: code entry 3917 // r0: code entry
3918 // r1: function 3918 // r1: function
3919 // r2: receiver 3919 // r2: receiver
3920 // r3: argc 3920 // r3: argc
3921 3921
3922 // Setup argv in r4. 3922 // Set up argv in r4.
3923 int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize; 3923 int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize;
3924 if (CpuFeatures::IsSupported(VFP3)) { 3924 if (CpuFeatures::IsSupported(VFP3)) {
3925 offset_to_argv += kNumDoubleCalleeSaved * kDoubleSize; 3925 offset_to_argv += kNumDoubleCalleeSaved * kDoubleSize;
3926 } 3926 }
3927 __ ldr(r4, MemOperand(sp, offset_to_argv)); 3927 __ ldr(r4, MemOperand(sp, offset_to_argv));
3928 3928
3929 // Push a frame with special values setup to mark it as an entry frame. 3929 // Push a frame with special values setup to mark it as an entry frame.
3930 // r0: code entry 3930 // r0: code entry
3931 // r1: function 3931 // r1: function
3932 // r2: receiver 3932 // r2: receiver
3933 // r3: argc 3933 // r3: argc
3934 // r4: argv 3934 // r4: argv
3935 Isolate* isolate = masm->isolate(); 3935 Isolate* isolate = masm->isolate();
3936 __ mov(r8, Operand(-1)); // Push a bad frame pointer to fail if it is used. 3936 __ mov(r8, Operand(-1)); // Push a bad frame pointer to fail if it is used.
3937 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 3937 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
3938 __ mov(r7, Operand(Smi::FromInt(marker))); 3938 __ mov(r7, Operand(Smi::FromInt(marker)));
3939 __ mov(r6, Operand(Smi::FromInt(marker))); 3939 __ mov(r6, Operand(Smi::FromInt(marker)));
3940 __ mov(r5, 3940 __ mov(r5,
3941 Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate))); 3941 Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
3942 __ ldr(r5, MemOperand(r5)); 3942 __ ldr(r5, MemOperand(r5));
3943 __ Push(r8, r7, r6, r5); 3943 __ Push(r8, r7, r6, r5);
3944 3944
3945 // Setup frame pointer for the frame to be pushed. 3945 // Set up frame pointer for the frame to be pushed.
3946 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); 3946 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
3947 3947
3948 // If this is the outermost JS call, set js_entry_sp value. 3948 // If this is the outermost JS call, set js_entry_sp value.
3949 Label non_outermost_js; 3949 Label non_outermost_js;
3950 ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate); 3950 ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate);
3951 __ mov(r5, Operand(ExternalReference(js_entry_sp))); 3951 __ mov(r5, Operand(ExternalReference(js_entry_sp)));
3952 __ ldr(r6, MemOperand(r5)); 3952 __ ldr(r6, MemOperand(r5));
3953 __ cmp(r6, Operand::Zero()); 3953 __ cmp(r6, Operand::Zero());
3954 __ b(ne, &non_outermost_js); 3954 __ b(ne, &non_outermost_js);
3955 __ str(fp, MemOperand(r5)); 3955 __ str(fp, MemOperand(r5));
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4074 ASSERT(!ReturnTrueFalseObject() || HasCallSiteInlineCheck()); 4074 ASSERT(!ReturnTrueFalseObject() || HasCallSiteInlineCheck());
4075 4075
4076 // Fixed register usage throughout the stub: 4076 // Fixed register usage throughout the stub:
4077 const Register object = r0; // Object (lhs). 4077 const Register object = r0; // Object (lhs).
4078 Register map = r3; // Map of the object. 4078 Register map = r3; // Map of the object.
4079 const Register function = r1; // Function (rhs). 4079 const Register function = r1; // Function (rhs).
4080 const Register prototype = r4; // Prototype of the function. 4080 const Register prototype = r4; // Prototype of the function.
4081 const Register inline_site = r9; 4081 const Register inline_site = r9;
4082 const Register scratch = r2; 4082 const Register scratch = r2;
4083 4083
4084 const int32_t kDeltaToLoadBoolResult = 3 * kPointerSize; 4084 const int32_t kDeltaToLoadBoolResult = 4 * kPointerSize;
4085 4085
4086 Label slow, loop, is_instance, is_not_instance, not_js_object; 4086 Label slow, loop, is_instance, is_not_instance, not_js_object;
4087 4087
4088 if (!HasArgsInRegisters()) { 4088 if (!HasArgsInRegisters()) {
4089 __ ldr(object, MemOperand(sp, 1 * kPointerSize)); 4089 __ ldr(object, MemOperand(sp, 1 * kPointerSize));
4090 __ ldr(function, MemOperand(sp, 0)); 4090 __ ldr(function, MemOperand(sp, 0));
4091 } 4091 }
4092 4092
4093 // Check that the left hand is a JS object and load map. 4093 // Check that the left hand is a JS object and load map.
4094 __ JumpIfSmi(object, &not_js_object); 4094 __ JumpIfSmi(object, &not_js_object);
(...skipping 30 matching lines...) Expand all
4125 } else { 4125 } else {
4126 ASSERT(HasArgsInRegisters()); 4126 ASSERT(HasArgsInRegisters());
4127 // Patch the (relocated) inlined map check. 4127 // Patch the (relocated) inlined map check.
4128 4128
4129 // The offset was stored in r4 safepoint slot. 4129 // The offset was stored in r4 safepoint slot.
4130 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal) 4130 // (See LCodeGen::DoDeferredLInstanceOfKnownGlobal)
4131 __ LoadFromSafepointRegisterSlot(scratch, r4); 4131 __ LoadFromSafepointRegisterSlot(scratch, r4);
4132 __ sub(inline_site, lr, scratch); 4132 __ sub(inline_site, lr, scratch);
4133 // Get the map location in scratch and patch it. 4133 // Get the map location in scratch and patch it.
4134 __ GetRelocatedValueLocation(inline_site, scratch); 4134 __ GetRelocatedValueLocation(inline_site, scratch);
4135 __ str(map, MemOperand(scratch)); 4135 __ ldr(scratch, MemOperand(scratch));
4136 __ str(map, FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
4136 } 4137 }
4137 4138
4138 // Register mapping: r3 is object map and r4 is function prototype. 4139 // Register mapping: r3 is object map and r4 is function prototype.
4139 // Get prototype of object into r2. 4140 // Get prototype of object into r2.
4140 __ ldr(scratch, FieldMemOperand(map, Map::kPrototypeOffset)); 4141 __ ldr(scratch, FieldMemOperand(map, Map::kPrototypeOffset));
4141 4142
4142 // We don't need map any more. Use it as a scratch register. 4143 // We don't need map any more. Use it as a scratch register.
4143 Register scratch2 = map; 4144 Register scratch2 = map;
4144 map = no_reg; 4145 map = no_reg;
4145 4146
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
4394 // r0 = address of new object (tagged) 4395 // r0 = address of new object (tagged)
4395 // r1 = mapped parameter count (tagged) 4396 // r1 = mapped parameter count (tagged)
4396 // r2 = argument count (tagged) 4397 // r2 = argument count (tagged)
4397 // r4 = address of boilerplate object (tagged) 4398 // r4 = address of boilerplate object (tagged)
4398 // Copy the JS object part. 4399 // Copy the JS object part.
4399 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { 4400 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
4400 __ ldr(r3, FieldMemOperand(r4, i)); 4401 __ ldr(r3, FieldMemOperand(r4, i));
4401 __ str(r3, FieldMemOperand(r0, i)); 4402 __ str(r3, FieldMemOperand(r0, i));
4402 } 4403 }
4403 4404
4404 // Setup the callee in-object property. 4405 // Set up the callee in-object property.
4405 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); 4406 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
4406 __ ldr(r3, MemOperand(sp, 2 * kPointerSize)); 4407 __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
4407 const int kCalleeOffset = JSObject::kHeaderSize + 4408 const int kCalleeOffset = JSObject::kHeaderSize +
4408 Heap::kArgumentsCalleeIndex * kPointerSize; 4409 Heap::kArgumentsCalleeIndex * kPointerSize;
4409 __ str(r3, FieldMemOperand(r0, kCalleeOffset)); 4410 __ str(r3, FieldMemOperand(r0, kCalleeOffset));
4410 4411
4411 // Use the length (smi tagged) and set that as an in-object property too. 4412 // Use the length (smi tagged) and set that as an in-object property too.
4412 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); 4413 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
4413 const int kLengthOffset = JSObject::kHeaderSize + 4414 const int kLengthOffset = JSObject::kHeaderSize +
4414 Heap::kArgumentsLengthIndex * kPointerSize; 4415 Heap::kArgumentsLengthIndex * kPointerSize;
4415 __ str(r2, FieldMemOperand(r0, kLengthOffset)); 4416 __ str(r2, FieldMemOperand(r0, kLengthOffset));
4416 4417
4417 // Setup the elements pointer in the allocated arguments object. 4418 // Set up the elements pointer in the allocated arguments object.
4418 // If we allocated a parameter map, r4 will point there, otherwise 4419 // If we allocated a parameter map, r4 will point there, otherwise
4419 // it will point to the backing store. 4420 // it will point to the backing store.
4420 __ add(r4, r0, Operand(Heap::kArgumentsObjectSize)); 4421 __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
4421 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 4422 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4422 4423
4423 // r0 = address of new object (tagged) 4424 // r0 = address of new object (tagged)
4424 // r1 = mapped parameter count (tagged) 4425 // r1 = mapped parameter count (tagged)
4425 // r2 = argument count (tagged) 4426 // r2 = argument count (tagged)
4426 // r4 = address of parameter map or backing store (tagged) 4427 // r4 = address of parameter map or backing store (tagged)
4427 // Initialize parameter map. If there are no mapped arguments, we're done. 4428 // Initialize parameter map. If there are no mapped arguments, we're done.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
4502 4503
4503 __ bind(&arguments_test); 4504 __ bind(&arguments_test);
4504 __ cmp(r9, Operand(r2)); 4505 __ cmp(r9, Operand(r2));
4505 __ b(lt, &arguments_loop); 4506 __ b(lt, &arguments_loop);
4506 4507
4507 // Return and remove the on-stack parameters. 4508 // Return and remove the on-stack parameters.
4508 __ add(sp, sp, Operand(3 * kPointerSize)); 4509 __ add(sp, sp, Operand(3 * kPointerSize));
4509 __ Ret(); 4510 __ Ret();
4510 4511
4511 // Do the runtime call to allocate the arguments object. 4512 // Do the runtime call to allocate the arguments object.
4512 // r2 = argument count (taggged) 4513 // r2 = argument count (tagged)
4513 __ bind(&runtime); 4514 __ bind(&runtime);
4514 __ str(r2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count. 4515 __ str(r2, MemOperand(sp, 0 * kPointerSize)); // Patch argument count.
4515 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); 4516 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
4516 } 4517 }
4517 4518
4518 4519
4519 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { 4520 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
4520 // sp[0] : number of parameters 4521 // sp[0] : number of parameters
4521 // sp[4] : receiver displacement 4522 // sp[4] : receiver displacement
4522 // sp[8] : function 4523 // sp[8] : function
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4575 Heap::kArgumentsLengthIndex * kPointerSize)); 4576 Heap::kArgumentsLengthIndex * kPointerSize));
4576 4577
4577 // If there are no actual arguments, we're done. 4578 // If there are no actual arguments, we're done.
4578 Label done; 4579 Label done;
4579 __ cmp(r1, Operand(0, RelocInfo::NONE)); 4580 __ cmp(r1, Operand(0, RelocInfo::NONE));
4580 __ b(eq, &done); 4581 __ b(eq, &done);
4581 4582
4582 // Get the parameters pointer from the stack. 4583 // Get the parameters pointer from the stack.
4583 __ ldr(r2, MemOperand(sp, 1 * kPointerSize)); 4584 __ ldr(r2, MemOperand(sp, 1 * kPointerSize));
4584 4585
4585 // Setup the elements pointer in the allocated arguments object and 4586 // Set up the elements pointer in the allocated arguments object and
4586 // initialize the header in the elements fixed array. 4587 // initialize the header in the elements fixed array.
4587 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict)); 4588 __ add(r4, r0, Operand(Heap::kArgumentsObjectSizeStrict));
4588 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); 4589 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
4589 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex); 4590 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
4590 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset)); 4591 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
4591 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset)); 4592 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
4592 // Untag the length for the loop. 4593 // Untag the length for the loop.
4593 __ mov(r1, Operand(r1, LSR, kSmiTagSize)); 4594 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
4594 4595
4595 // Copy the fixed array slots. 4596 // Copy the fixed array slots.
4596 Label loop; 4597 Label loop;
4597 // Setup r4 to point to the first array slot. 4598 // Set up r4 to point to the first array slot.
4598 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4599 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4599 __ bind(&loop); 4600 __ bind(&loop);
4600 // Pre-decrement r2 with kPointerSize on each iteration. 4601 // Pre-decrement r2 with kPointerSize on each iteration.
4601 // Pre-decrement in order to skip receiver. 4602 // Pre-decrement in order to skip receiver.
4602 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex)); 4603 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
4603 // Post-increment r4 with kPointerSize on each iteration. 4604 // Post-increment r4 with kPointerSize on each iteration.
4604 __ str(r3, MemOperand(r4, kPointerSize, PostIndex)); 4605 __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
4605 __ sub(r1, r1, Operand(1)); 4606 __ sub(r1, r1, Operand(1));
4606 __ cmp(r1, Operand(0, RelocInfo::NONE)); 4607 __ cmp(r1, Operand(0, RelocInfo::NONE));
4607 __ b(ne, &loop); 4608 __ b(ne, &loop);
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
5202 { 5203 {
5203 Handle<Code> adaptor = 5204 Handle<Code> adaptor =
5204 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 5205 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
5205 __ Jump(adaptor, RelocInfo::CODE_TARGET); 5206 __ Jump(adaptor, RelocInfo::CODE_TARGET);
5206 } 5207 }
5207 5208
5208 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 5209 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
5209 // of the original receiver from the call site). 5210 // of the original receiver from the call site).
5210 __ bind(&non_function); 5211 __ bind(&non_function);
5211 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); 5212 __ str(r1, MemOperand(sp, argc_ * kPointerSize));
5212 __ mov(r0, Operand(argc_)); // Setup the number of arguments. 5213 __ mov(r0, Operand(argc_)); // Set up the number of arguments.
5213 __ mov(r2, Operand(0, RelocInfo::NONE)); 5214 __ mov(r2, Operand(0, RelocInfo::NONE));
5214 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5215 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5215 __ SetCallKind(r5, CALL_AS_METHOD); 5216 __ SetCallKind(r5, CALL_AS_METHOD);
5216 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 5217 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
5217 RelocInfo::CODE_TARGET); 5218 RelocInfo::CODE_TARGET);
5218 } 5219 }
5219 5220
5220 5221
5221 // Unfortunately you have to run without snapshots to see most of these 5222 // Unfortunately you have to run without snapshots to see most of these
5222 // names in the profile since most compare stubs end up in the snapshot. 5223 // names in the profile since most compare stubs end up in the snapshot.
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
5723 Register result = candidate; 5724 Register result = candidate;
5724 __ bind(&found_in_symbol_table); 5725 __ bind(&found_in_symbol_table);
5725 __ Move(r0, result); 5726 __ Move(r0, result);
5726 } 5727 }
5727 5728
5728 5729
5729 void StringHelper::GenerateHashInit(MacroAssembler* masm, 5730 void StringHelper::GenerateHashInit(MacroAssembler* masm,
5730 Register hash, 5731 Register hash,
5731 Register character) { 5732 Register character) {
5732 // hash = character + (character << 10); 5733 // hash = character + (character << 10);
5733 __ LoadRoot(hash, Heap::kStringHashSeedRootIndex); 5734 __ LoadRoot(hash, Heap::kHashSeedRootIndex);
5734 // Untag smi seed and add the character. 5735 // Untag smi seed and add the character.
5735 __ add(hash, character, Operand(hash, LSR, kSmiTagSize)); 5736 __ add(hash, character, Operand(hash, LSR, kSmiTagSize));
5736 // hash += hash << 10; 5737 // hash += hash << 10;
5737 __ add(hash, hash, Operand(hash, LSL, 10)); 5738 __ add(hash, hash, Operand(hash, LSL, 10));
5738 // hash ^= hash >> 6; 5739 // hash ^= hash >> 6;
5739 __ eor(hash, hash, Operand(hash, LSR, 6)); 5740 __ eor(hash, hash, Operand(hash, LSR, 6));
5740 } 5741 }
5741 5742
5742 5743
5743 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm, 5744 void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
5744 Register hash, 5745 Register hash,
5745 Register character) { 5746 Register character) {
5746 // hash += character; 5747 // hash += character;
5747 __ add(hash, hash, Operand(character)); 5748 __ add(hash, hash, Operand(character));
5748 // hash += hash << 10; 5749 // hash += hash << 10;
5749 __ add(hash, hash, Operand(hash, LSL, 10)); 5750 __ add(hash, hash, Operand(hash, LSL, 10));
5750 // hash ^= hash >> 6; 5751 // hash ^= hash >> 6;
5751 __ eor(hash, hash, Operand(hash, LSR, 6)); 5752 __ eor(hash, hash, Operand(hash, LSR, 6));
5752 } 5753 }
5753 5754
5754 5755
5755 void StringHelper::GenerateHashGetHash(MacroAssembler* masm, 5756 void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
5756 Register hash) { 5757 Register hash) {
5757 // hash += hash << 3; 5758 // hash += hash << 3;
5758 __ add(hash, hash, Operand(hash, LSL, 3)); 5759 __ add(hash, hash, Operand(hash, LSL, 3));
5759 // hash ^= hash >> 11; 5760 // hash ^= hash >> 11;
5760 __ eor(hash, hash, Operand(hash, LSR, 11)); 5761 __ eor(hash, hash, Operand(hash, LSR, 11));
5761 // hash += hash << 15; 5762 // hash += hash << 15;
5762 __ add(hash, hash, Operand(hash, LSL, 15), SetCC); 5763 __ add(hash, hash, Operand(hash, LSL, 15));
5763 5764
5764 uint32_t kHashShiftCutOffMask = (1 << (32 - String::kHashShift)) - 1; 5765 __ and_(hash, hash, Operand(String::kHashBitMask), SetCC);
5765 __ and_(hash, hash, Operand(kHashShiftCutOffMask));
5766 5766
5767 // if (hash == 0) hash = 27; 5767 // if (hash == 0) hash = 27;
5768 __ mov(hash, Operand(27), LeaveCC, eq); 5768 __ mov(hash, Operand(StringHasher::kZeroHash), LeaveCC, eq);
5769 } 5769 }
5770 5770
5771 5771
5772 void SubStringStub::Generate(MacroAssembler* masm) { 5772 void SubStringStub::Generate(MacroAssembler* masm) {
5773 Label runtime; 5773 Label runtime;
5774 5774
5775 // Stack frame on entry. 5775 // Stack frame on entry.
5776 // lr: return address 5776 // lr: return address
5777 // sp[0]: to 5777 // sp[0]: to
5778 // sp[4]: from 5778 // sp[4]: from
(...skipping 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after
7314 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r10, 7314 __ StoreNumberToDoubleElements(r0, r3, r1, r5, r6, r7, r9, r10,
7315 &slow_elements); 7315 &slow_elements);
7316 __ Ret(); 7316 __ Ret();
7317 } 7317 }
7318 7318
7319 #undef __ 7319 #undef __
7320 7320
7321 } } // namespace v8::internal 7321 } } // namespace v8::internal
7322 7322
7323 #endif // V8_TARGET_ARCH_ARM 7323 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/cpu-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698