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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 if (cc == equal && strict()) { | 870 if (cc == equal && strict()) { |
871 Label slow; // Fallthrough label. | 871 Label slow; // Fallthrough label. |
872 Label not_smis; | 872 Label not_smis; |
873 // If we're doing a strict equality comparison, we don't have to do | 873 // If we're doing a strict equality comparison, we don't have to do |
874 // type conversion, so we generate code to do fast comparison for objects | 874 // type conversion, so we generate code to do fast comparison for objects |
875 // and oddballs. Non-smi numbers and strings still go through the usual | 875 // and oddballs. Non-smi numbers and strings still go through the usual |
876 // slow-case code. | 876 // slow-case code. |
877 // If either is a Smi (we know that not both are), then they can only | 877 // If either is a Smi (we know that not both are), then they can only |
878 // be equal if the other is a HeapNumber. If so, use the slow case. | 878 // be equal if the other is a HeapNumber. If so, use the slow case. |
879 STATIC_ASSERT(kSmiTag == 0); | 879 STATIC_ASSERT(kSmiTag == 0); |
880 DCHECK_EQ(static_cast<Smi*>(0), Smi::kZero); | 880 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); |
881 __ mov(ecx, Immediate(kSmiTagMask)); | 881 __ mov(ecx, Immediate(kSmiTagMask)); |
882 __ and_(ecx, eax); | 882 __ and_(ecx, eax); |
883 __ test(ecx, edx); | 883 __ test(ecx, edx); |
884 __ j(not_zero, ¬_smis, Label::kNear); | 884 __ j(not_zero, ¬_smis, Label::kNear); |
885 // One operand is a smi. | 885 // One operand is a smi. |
886 | 886 |
887 // Check whether the non-smi is a heap number. | 887 // Check whether the non-smi is a heap number. |
888 STATIC_ASSERT(kSmiTagMask == 1); | 888 STATIC_ASSERT(kSmiTagMask == 1); |
889 // ecx still holds eax & kSmiTag, which is either zero or one. | 889 // ecx still holds eax & kSmiTag, which is either zero or one. |
890 __ sub(ecx, Immediate(0x01)); | 890 __ sub(ecx, Immediate(0x01)); |
(...skipping 2412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3303 // - esp[16] -- slot | 3303 // - esp[16] -- slot |
3304 // - esp[20] -- value | 3304 // - esp[20] -- value |
3305 // | 3305 // |
3306 // Required stack layout for handler call (see StoreWithVectorDescriptor): | 3306 // Required stack layout for handler call (see StoreWithVectorDescriptor): |
3307 // - esp[0] -- return address | 3307 // - esp[0] -- return address |
3308 // - esp[4] -- vector | 3308 // - esp[4] -- vector |
3309 // - esp[8] -- slot | 3309 // - esp[8] -- slot |
3310 // - esp[12] -- value | 3310 // - esp[12] -- value |
3311 // - receiver, key, handler in registers. | 3311 // - receiver, key, handler in registers. |
3312 Register counter = key; | 3312 Register counter = key; |
3313 __ mov(counter, Immediate(Smi::kZero)); | 3313 __ mov(counter, Immediate(Smi::FromInt(0))); |
3314 __ bind(&next_loop); | 3314 __ bind(&next_loop); |
3315 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 3315 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
3316 FixedArray::kHeaderSize)); | 3316 FixedArray::kHeaderSize)); |
3317 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 3317 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
3318 __ j(not_equal, &prepare_next); | 3318 __ j(not_equal, &prepare_next); |
3319 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 3319 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
3320 FixedArray::kHeaderSize + kPointerSize)); | 3320 FixedArray::kHeaderSize + kPointerSize)); |
3321 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); | 3321 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); |
3322 __ j(not_equal, &transition_call); | 3322 __ j(not_equal, &transition_call); |
3323 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 3323 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4008 Label allocate, done_allocate; | 4008 Label allocate, done_allocate; |
4009 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, NO_ALLOCATION_FLAGS); | 4009 __ Allocate(JSArray::kSize, eax, edx, ecx, &allocate, NO_ALLOCATION_FLAGS); |
4010 __ bind(&done_allocate); | 4010 __ bind(&done_allocate); |
4011 | 4011 |
4012 // Setup the rest parameter array in rax. | 4012 // Setup the rest parameter array in rax. |
4013 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); | 4013 __ LoadGlobalFunction(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, ecx); |
4014 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); | 4014 __ mov(FieldOperand(eax, JSArray::kMapOffset), ecx); |
4015 __ mov(ecx, isolate()->factory()->empty_fixed_array()); | 4015 __ mov(ecx, isolate()->factory()->empty_fixed_array()); |
4016 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); | 4016 __ mov(FieldOperand(eax, JSArray::kPropertiesOffset), ecx); |
4017 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); | 4017 __ mov(FieldOperand(eax, JSArray::kElementsOffset), ecx); |
4018 __ mov(FieldOperand(eax, JSArray::kLengthOffset), Immediate(Smi::kZero)); | 4018 __ mov(FieldOperand(eax, JSArray::kLengthOffset), |
| 4019 Immediate(Smi::FromInt(0))); |
4019 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); | 4020 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize); |
4020 __ Ret(); | 4021 __ Ret(); |
4021 | 4022 |
4022 // Fall back to %AllocateInNewSpace. | 4023 // Fall back to %AllocateInNewSpace. |
4023 __ bind(&allocate); | 4024 __ bind(&allocate); |
4024 { | 4025 { |
4025 FrameScope scope(masm, StackFrame::INTERNAL); | 4026 FrameScope scope(masm, StackFrame::INTERNAL); |
4026 __ Push(Smi::FromInt(JSArray::kSize)); | 4027 __ Push(Smi::FromInt(JSArray::kSize)); |
4027 __ CallRuntime(Runtime::kAllocateInNewSpace); | 4028 __ CallRuntime(Runtime::kAllocateInNewSpace); |
4028 } | 4029 } |
(...skipping 20 matching lines...) Expand all Loading... |
4049 JSArray::kSize + FixedArray::kHeaderSize)); | 4050 JSArray::kSize + FixedArray::kHeaderSize)); |
4050 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); | 4051 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
4051 __ bind(&done_allocate); | 4052 __ bind(&done_allocate); |
4052 | 4053 |
4053 // Setup the elements array in edx. | 4054 // Setup the elements array in edx. |
4054 __ mov(FieldOperand(edx, FixedArray::kMapOffset), | 4055 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
4055 isolate()->factory()->fixed_array_map()); | 4056 isolate()->factory()->fixed_array_map()); |
4056 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); | 4057 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
4057 { | 4058 { |
4058 Label loop, done_loop; | 4059 Label loop, done_loop; |
4059 __ Move(ecx, Smi::kZero); | 4060 __ Move(ecx, Smi::FromInt(0)); |
4060 __ bind(&loop); | 4061 __ bind(&loop); |
4061 __ cmp(ecx, eax); | 4062 __ cmp(ecx, eax); |
4062 __ j(equal, &done_loop, Label::kNear); | 4063 __ j(equal, &done_loop, Label::kNear); |
4063 __ mov(edi, Operand(ebx, 0 * kPointerSize)); | 4064 __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
4064 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, | 4065 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
4065 FixedArray::kHeaderSize), | 4066 FixedArray::kHeaderSize), |
4066 edi); | 4067 edi); |
4067 __ sub(ebx, Immediate(1 * kPointerSize)); | 4068 __ sub(ebx, Immediate(1 * kPointerSize)); |
4068 __ add(ecx, Immediate(Smi::FromInt(1))); | 4069 __ add(ecx, Immediate(Smi::FromInt(1))); |
4069 __ jmp(&loop); | 4070 __ jmp(&loop); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4436 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize)); | 4437 JSStrictArgumentsObject::kSize + FixedArray::kHeaderSize)); |
4437 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); | 4438 __ Allocate(ecx, edx, edi, no_reg, &allocate, NO_ALLOCATION_FLAGS); |
4438 __ bind(&done_allocate); | 4439 __ bind(&done_allocate); |
4439 | 4440 |
4440 // Setup the elements array in edx. | 4441 // Setup the elements array in edx. |
4441 __ mov(FieldOperand(edx, FixedArray::kMapOffset), | 4442 __ mov(FieldOperand(edx, FixedArray::kMapOffset), |
4442 isolate()->factory()->fixed_array_map()); | 4443 isolate()->factory()->fixed_array_map()); |
4443 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); | 4444 __ mov(FieldOperand(edx, FixedArray::kLengthOffset), eax); |
4444 { | 4445 { |
4445 Label loop, done_loop; | 4446 Label loop, done_loop; |
4446 __ Move(ecx, Smi::kZero); | 4447 __ Move(ecx, Smi::FromInt(0)); |
4447 __ bind(&loop); | 4448 __ bind(&loop); |
4448 __ cmp(ecx, eax); | 4449 __ cmp(ecx, eax); |
4449 __ j(equal, &done_loop, Label::kNear); | 4450 __ j(equal, &done_loop, Label::kNear); |
4450 __ mov(edi, Operand(ebx, 0 * kPointerSize)); | 4451 __ mov(edi, Operand(ebx, 0 * kPointerSize)); |
4451 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, | 4452 __ mov(FieldOperand(edx, ecx, times_half_pointer_size, |
4452 FixedArray::kHeaderSize), | 4453 FixedArray::kHeaderSize), |
4453 edi); | 4454 edi); |
4454 __ sub(ebx, Immediate(1 * kPointerSize)); | 4455 __ sub(ebx, Immediate(1 * kPointerSize)); |
4455 __ add(ecx, Immediate(Smi::FromInt(1))); | 4456 __ add(ecx, Immediate(Smi::FromInt(1))); |
4456 __ jmp(&loop); | 4457 __ jmp(&loop); |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4954 DCHECK(!AreAliased(receiver, holder, callback, scratch)); | 4955 DCHECK(!AreAliased(receiver, holder, callback, scratch)); |
4955 | 4956 |
4956 __ pop(scratch); // Pop return address to extend the frame. | 4957 __ pop(scratch); // Pop return address to extend the frame. |
4957 __ push(receiver); | 4958 __ push(receiver); |
4958 __ push(FieldOperand(callback, AccessorInfo::kDataOffset)); | 4959 __ push(FieldOperand(callback, AccessorInfo::kDataOffset)); |
4959 __ PushRoot(Heap::kUndefinedValueRootIndex); // ReturnValue | 4960 __ PushRoot(Heap::kUndefinedValueRootIndex); // ReturnValue |
4960 // ReturnValue default value | 4961 // ReturnValue default value |
4961 __ PushRoot(Heap::kUndefinedValueRootIndex); | 4962 __ PushRoot(Heap::kUndefinedValueRootIndex); |
4962 __ push(Immediate(ExternalReference::isolate_address(isolate()))); | 4963 __ push(Immediate(ExternalReference::isolate_address(isolate()))); |
4963 __ push(holder); | 4964 __ push(holder); |
4964 __ push(Immediate(Smi::kZero)); // should_throw_on_error -> false | 4965 __ push(Immediate(Smi::FromInt(0))); // should_throw_on_error -> false |
4965 __ push(FieldOperand(callback, AccessorInfo::kNameOffset)); | 4966 __ push(FieldOperand(callback, AccessorInfo::kNameOffset)); |
4966 __ push(scratch); // Restore return address. | 4967 __ push(scratch); // Restore return address. |
4967 | 4968 |
4968 // v8::PropertyCallbackInfo::args_ array and name handle. | 4969 // v8::PropertyCallbackInfo::args_ array and name handle. |
4969 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 4970 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
4970 | 4971 |
4971 // Allocate v8::PropertyCallbackInfo object, arguments for callback and | 4972 // Allocate v8::PropertyCallbackInfo object, arguments for callback and |
4972 // space for optional callback address parameter (in case CPU profiler is | 4973 // space for optional callback address parameter (in case CPU profiler is |
4973 // active) in non-GCed stack space. | 4974 // active) in non-GCed stack space. |
4974 const int kApiArgc = 3 + 1; | 4975 const int kApiArgc = 3 + 1; |
(...skipping 30 matching lines...) Expand all Loading... |
5005 kStackUnwindSpace, nullptr, return_value_operand, | 5006 kStackUnwindSpace, nullptr, return_value_operand, |
5006 NULL); | 5007 NULL); |
5007 } | 5008 } |
5008 | 5009 |
5009 #undef __ | 5010 #undef __ |
5010 | 5011 |
5011 } // namespace internal | 5012 } // namespace internal |
5012 } // namespace v8 | 5013 } // namespace v8 |
5013 | 5014 |
5014 #endif // V8_TARGET_ARCH_X87 | 5015 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |