OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 if (cc == equal && strict()) { | 1055 if (cc == equal && strict()) { |
1056 Label slow; // Fallthrough label. | 1056 Label slow; // Fallthrough label. |
1057 Label not_smis; | 1057 Label not_smis; |
1058 // If we're doing a strict equality comparison, we don't have to do | 1058 // If we're doing a strict equality comparison, we don't have to do |
1059 // type conversion, so we generate code to do fast comparison for objects | 1059 // type conversion, so we generate code to do fast comparison for objects |
1060 // and oddballs. Non-smi numbers and strings still go through the usual | 1060 // and oddballs. Non-smi numbers and strings still go through the usual |
1061 // slow-case code. | 1061 // slow-case code. |
1062 // If either is a Smi (we know that not both are), then they can only | 1062 // If either is a Smi (we know that not both are), then they can only |
1063 // be equal if the other is a HeapNumber. If so, use the slow case. | 1063 // be equal if the other is a HeapNumber. If so, use the slow case. |
1064 STATIC_ASSERT(kSmiTag == 0); | 1064 STATIC_ASSERT(kSmiTag == 0); |
1065 DCHECK_EQ(static_cast<Smi*>(0), Smi::kZero); | 1065 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); |
1066 __ mov(ecx, Immediate(kSmiTagMask)); | 1066 __ mov(ecx, Immediate(kSmiTagMask)); |
1067 __ and_(ecx, eax); | 1067 __ and_(ecx, eax); |
1068 __ test(ecx, edx); | 1068 __ test(ecx, edx); |
1069 __ j(not_zero, ¬_smis, Label::kNear); | 1069 __ j(not_zero, ¬_smis, Label::kNear); |
1070 // One operand is a smi. | 1070 // One operand is a smi. |
1071 | 1071 |
1072 // Check whether the non-smi is a heap number. | 1072 // Check whether the non-smi is a heap number. |
1073 STATIC_ASSERT(kSmiTagMask == 1); | 1073 STATIC_ASSERT(kSmiTagMask == 1); |
1074 // ecx still holds eax & kSmiTag, which is either zero or one. | 1074 // ecx still holds eax & kSmiTag, which is either zero or one. |
1075 __ sub(ecx, Immediate(0x01)); | 1075 __ sub(ecx, Immediate(0x01)); |
(...skipping 2404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3480 // - esp[16] -- slot | 3480 // - esp[16] -- slot |
3481 // - esp[20] -- value | 3481 // - esp[20] -- value |
3482 // | 3482 // |
3483 // Required stack layout for handler call (see StoreWithVectorDescriptor): | 3483 // Required stack layout for handler call (see StoreWithVectorDescriptor): |
3484 // - esp[0] -- return address | 3484 // - esp[0] -- return address |
3485 // - esp[4] -- vector | 3485 // - esp[4] -- vector |
3486 // - esp[8] -- slot | 3486 // - esp[8] -- slot |
3487 // - esp[12] -- value | 3487 // - esp[12] -- value |
3488 // - receiver, key, handler in registers. | 3488 // - receiver, key, handler in registers. |
3489 Register counter = key; | 3489 Register counter = key; |
3490 __ mov(counter, Immediate(Smi::kZero)); | 3490 __ mov(counter, Immediate(Smi::FromInt(0))); |
3491 __ bind(&next_loop); | 3491 __ bind(&next_loop); |
3492 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 3492 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
3493 FixedArray::kHeaderSize)); | 3493 FixedArray::kHeaderSize)); |
3494 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 3494 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
3495 __ j(not_equal, &prepare_next); | 3495 __ j(not_equal, &prepare_next); |
3496 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 3496 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
3497 FixedArray::kHeaderSize + kPointerSize)); | 3497 FixedArray::kHeaderSize + kPointerSize)); |
3498 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); | 3498 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); |
3499 __ j(not_equal, &transition_call); | 3499 __ j(not_equal, &transition_call); |
3500 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 3500 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4203 Label allocate, done_allocate; | 4203 Label allocate, done_allocate; |
4204 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, NO_ALLOCATION_FLAGS); | 4204 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, NO_ALLOCATION_FLAGS); |
4205 __ bind(&done_allocate); | 4205 __ bind(&done_allocate); |
4206 | 4206 |
4207 // Setup the rest parameter array in rax. | 4207 // Setup the rest parameter array in rax. |
4208 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); | 4208 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
4209 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); | 4209 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); |
4210 __ mov(ecx, isolate()->factory()->empty_fixed_array()); | 4210 __ mov(ecx, isolate()->factory()->empty_fixed_array()); |
4211 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); | 4211 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); |
4212 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); | 4212 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); |
4213 __ mov(FieldOperand(eax, JSArray::kLengthOffset), Immediate(Smi::kZero)); | 4213 __ mov(FieldOperand(eax, JSArray::kLengthOffset), |
| 4214 Immediate(Smi::FromInt(0))); |
4214 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); | 4215 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
4215 __ Ret(); | 4216 __ Ret(); |
4216 | 4217 |
4217 // Fall back to %AllocateInNewSpace. | 4218 // Fall back to %AllocateInNewSpace. |
4218 __ bind(&allocate); | 4219 __ bind(&allocate); |
4219 { | 4220 { |
4220 FrameScope scope(masm, StackFrame::INTERNAL); | 4221 FrameScope scope(masm, StackFrame::INTERNAL); |
4221 __ Push(Smi::FromInt(JSArray::kSize)); | 4222 __ Push(Smi::FromInt(JSArray::kSize)); |
4222 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4223 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4223 } | 4224 } |
(...skipping 20 matching lines...) Expand all Loading... |
4244 JSArray::kSize + FixedArray::kHeaderSize)); | 4245 JSArray::kSize + FixedArray::kHeaderSize)); |
4245 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); | 4246 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
4246 __ bind(&done_allocate); | 4247 __ bind(&done_allocate); |
4247 | 4248 |
4248 // Setup the elements array in edx. | 4249 // Setup the elements array in edx. |
4249 __ mov(FieldOperand(edx, FixedArray::kMapOffset), | 4250 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
4250 isolate()->factory()->fixed_array_map()); | 4251 isolate()->factory()->fixed_array_map()); |
4251 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); | 4252 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
4252 { | 4253 { |
4253 Label loop, done_loop; | 4254 Label loop, done_loop; |
4254 __ Move(ecx, Smi::kZero); | 4255 __ Move(ecx, Smi::FromInt(0)); |
4255 __ bind(&loop); | 4256 __ bind(&loop); |
4256 __ cmp(ecx, eax); | 4257 __ cmp(ecx, eax); |
4257 __ j(equal, &done_loop, Label::kNear); | 4258 __ j(equal, &done_loop, Label::kNear); |
4258 __ mov(edi, Operand(ebx, 0 * kPointerSize)); | 4259 __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
4259 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, | 4260 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
4260 FixedArray::kHeaderSize), | 4261 FixedArray::kHeaderSize), |
4261 edi); | 4262 edi); |
4262 __ sub(ebx, Immediate(1 * kPointerSize)); | 4263 __ sub(ebx, Immediate(1 * kPointerSize)); |
4263 __ add(ecx, Immediate(Smi::FromInt(1))); | 4264 __ add(ecx, Immediate(Smi::FromInt(1))); |
4264 __ jmp(&loop); | 4265 __ jmp(&loop); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4633 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize)); | 4634 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize)); |
4634 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); | 4635 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
4635 __ bind(&done_allocate); | 4636 __ bind(&done_allocate); |
4636 | 4637 |
4637 // Setup the elements array in edx. | 4638 // Setup the elements array in edx. |
4638 __ mov(FieldOperand(edx, FixedArray::kMapOffset), | 4639 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
4639 isolate()->factory()->fixed_array_map()); | 4640 isolate()->factory()->fixed_array_map()); |
4640 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); | 4641 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
4641 { | 4642 { |
4642 Label loop, done_loop; | 4643 Label loop, done_loop; |
4643 __ Move(ecx, Smi::kZero); | 4644 __ Move(ecx, Smi::FromInt(0)); |
4644 __ bind(&loop); | 4645 __ bind(&loop); |
4645 __ cmp(ecx, eax); | 4646 __ cmp(ecx, eax); |
4646 __ j(equal, &done_loop, Label::kNear); | 4647 __ j(equal, &done_loop, Label::kNear); |
4647 __ mov(edi, Operand(ebx, 0 * kPointerSize)); | 4648 __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
4648 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, | 4649 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
4649 FixedArray::kHeaderSize), | 4650 FixedArray::kHeaderSize), |
4650 edi); | 4651 edi); |
4651 __ sub(ebx, Immediate(1 * kPointerSize)); | 4652 __ sub(ebx, Immediate(1 * kPointerSize)); |
4652 __ add(ecx, Immediate(Smi::FromInt(1))); | 4653 __ add(ecx, Immediate(Smi::FromInt(1))); |
4653 __ jmp(&loop); | 4654 __ jmp(&loop); |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5152 DCHECK(!AreAliased(receiver, holder, callback, scratch)); | 5153 DCHECK(!AreAliased(receiver, holder, callback, scratch)); |
5153 | 5154 |
5154 __ pop(scratch); // Pop return address to extend the frame. | 5155 __ pop(scratch); // Pop return address to extend the frame. |
5155 __ push(receiver); | 5156 __ push(receiver); |
5156 __ push(FieldOperand(callback, AccessorInfo::kDataOffset)); | 5157 __ push(FieldOperand(callback, AccessorInfo::kDataOffset)); |
5157 __ PushRoot(Heap::kUndefinedValueRootIndex); // ReturnValue | 5158 __ PushRoot(Heap::kUndefinedValueRootIndex); // ReturnValue |
5158 // ReturnValue default value | 5159 // ReturnValue default value |
5159 __ PushRoot(Heap::kUndefinedValueRootIndex); | 5160 __ PushRoot(Heap::kUndefinedValueRootIndex); |
5160 __ push(Immediate(ExternalReference::isolate_address(isolate()))); | 5161 __ push(Immediate(ExternalReference::isolate_address(isolate()))); |
5161 __ push(holder); | 5162 __ push(holder); |
5162 __ push(Immediate(Smi::kZero)); // should_throw_on_error -> false | 5163 __ push(Immediate(Smi::FromInt(0))); // should_throw_on_error -> false |
5163 __ push(FieldOperand(callback, AccessorInfo::kNameOffset)); | 5164 __ push(FieldOperand(callback, AccessorInfo::kNameOffset)); |
5164 __ push(scratch); // Restore return address. | 5165 __ push(scratch); // Restore return address. |
5165 | 5166 |
5166 // v8::PropertyCallbackInfo::args_ array and name handle. | 5167 // v8::PropertyCallbackInfo::args_ array and name handle. |
5167 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 5168 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
5168 | 5169 |
5169 // Allocate v8::PropertyCallbackInfo object, arguments for callback and | 5170 // Allocate v8::PropertyCallbackInfo object, arguments for callback and |
5170 // space for optional callback address parameter (in case CPU profiler is | 5171 // space for optional callback address parameter (in case CPU profiler is |
5171 // active) in non-GCed stack space. | 5172 // active) in non-GCed stack space. |
5172 const int kApiArgc = 3 + 1; | 5173 const int kApiArgc = 3 + 1; |
(...skipping 30 matching lines...) Expand all Loading... |
5203 kStackUnwindSpace, nullptr, return_value_operand, | 5204 kStackUnwindSpace, nullptr, return_value_operand, |
5204 NULL); | 5205 NULL); |
5205 } | 5206 } |
5206 | 5207 |
5207 #undef __ | 5208 #undef __ |
5208 | 5209 |
5209 } // namespace internal | 5210 } // namespace internal |
5210 } // namespace v8 | 5211 } // namespace v8 |
5211 | 5212 |
5212 #endif // V8_TARGET_ARCH_IA32 | 5213 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |