| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { | 701 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { |
| 702 // Return address is on the stack. | 702 // Return address is on the stack. |
| 703 Label miss; | 703 Label miss; |
| 704 | 704 |
| 705 Register receiver = LoadDescriptor::ReceiverRegister(); | 705 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 706 Register index = LoadDescriptor::NameRegister(); | 706 Register index = LoadDescriptor::NameRegister(); |
| 707 Register scratch = edi; | 707 Register scratch = edi; |
| 708 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 708 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 709 Register result = eax; | 709 Register result = eax; |
| 710 DCHECK(!result.is(scratch)); | 710 DCHECK(!result.is(scratch)); |
| 711 DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) && | 711 DCHECK(!scratch.is(LoadWithVectorDescriptor::VectorRegister()) && |
| 712 result.is(VectorLoadICDescriptor::SlotRegister())); | 712 result.is(LoadDescriptor::SlotRegister())); |
| 713 | 713 |
| 714 // StringCharAtGenerator doesn't use the result register until it's passed | 714 // StringCharAtGenerator doesn't use the result register until it's passed |
| 715 // the different miss possibilities. If it did, we would have a conflict | 715 // the different miss possibilities. If it did, we would have a conflict |
| 716 // when FLAG_vector_ics is true. | 716 // when FLAG_vector_ics is true. |
| 717 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 717 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
| 718 &miss, // When not a string. | 718 &miss, // When not a string. |
| 719 &miss, // When not a number. | 719 &miss, // When not a number. |
| 720 &miss, // When index out of range. | 720 &miss, // When index out of range. |
| 721 STRING_INDEX_IS_ARRAY_INDEX, | 721 STRING_INDEX_IS_ARRAY_INDEX, |
| 722 RECEIVER_IS_STRING); | 722 RECEIVER_IS_STRING); |
| (...skipping 2239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2962 | 2962 |
| 2963 // Index is not a smi. | 2963 // Index is not a smi. |
| 2964 __ bind(&index_not_smi_); | 2964 __ bind(&index_not_smi_); |
| 2965 // If index is a heap number, try converting it to an integer. | 2965 // If index is a heap number, try converting it to an integer. |
| 2966 __ CheckMap(index_, | 2966 __ CheckMap(index_, |
| 2967 masm->isolate()->factory()->heap_number_map(), | 2967 masm->isolate()->factory()->heap_number_map(), |
| 2968 index_not_number_, | 2968 index_not_number_, |
| 2969 DONT_DO_SMI_CHECK); | 2969 DONT_DO_SMI_CHECK); |
| 2970 call_helper.BeforeCall(masm); | 2970 call_helper.BeforeCall(masm); |
| 2971 if (embed_mode == PART_OF_IC_HANDLER) { | 2971 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2972 __ push(VectorLoadICDescriptor::VectorRegister()); | 2972 __ push(LoadWithVectorDescriptor::VectorRegister()); |
| 2973 __ push(VectorLoadICDescriptor::SlotRegister()); | 2973 __ push(LoadDescriptor::SlotRegister()); |
| 2974 } | 2974 } |
| 2975 __ push(object_); | 2975 __ push(object_); |
| 2976 __ push(index_); // Consumed by runtime conversion function. | 2976 __ push(index_); // Consumed by runtime conversion function. |
| 2977 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 2977 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
| 2978 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 2978 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
| 2979 } else { | 2979 } else { |
| 2980 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 2980 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
| 2981 // NumberToSmi discards numbers that are not exact integers. | 2981 // NumberToSmi discards numbers that are not exact integers. |
| 2982 __ CallRuntime(Runtime::kNumberToSmi, 1); | 2982 __ CallRuntime(Runtime::kNumberToSmi, 1); |
| 2983 } | 2983 } |
| 2984 if (!index_.is(eax)) { | 2984 if (!index_.is(eax)) { |
| 2985 // Save the conversion result before the pop instructions below | 2985 // Save the conversion result before the pop instructions below |
| 2986 // have a chance to overwrite it. | 2986 // have a chance to overwrite it. |
| 2987 __ mov(index_, eax); | 2987 __ mov(index_, eax); |
| 2988 } | 2988 } |
| 2989 __ pop(object_); | 2989 __ pop(object_); |
| 2990 if (embed_mode == PART_OF_IC_HANDLER) { | 2990 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2991 __ pop(VectorLoadICDescriptor::SlotRegister()); | 2991 __ pop(LoadDescriptor::SlotRegister()); |
| 2992 __ pop(VectorLoadICDescriptor::VectorRegister()); | 2992 __ pop(LoadWithVectorDescriptor::VectorRegister()); |
| 2993 } | 2993 } |
| 2994 // Reload the instance type. | 2994 // Reload the instance type. |
| 2995 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 2995 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
| 2996 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 2996 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
| 2997 call_helper.AfterCall(masm); | 2997 call_helper.AfterCall(masm); |
| 2998 // If index is still not a smi, it must be out of range. | 2998 // If index is still not a smi, it must be out of range. |
| 2999 STATIC_ASSERT(kSmiTag == 0); | 2999 STATIC_ASSERT(kSmiTag == 0); |
| 3000 __ JumpIfNotSmi(index_, index_out_of_range_); | 3000 __ JumpIfNotSmi(index_, index_out_of_range_); |
| 3001 // Otherwise, return to the fast path. | 3001 // Otherwise, return to the fast path. |
| 3002 __ jmp(&got_smi_index_); | 3002 __ jmp(&got_smi_index_); |
| (...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4413 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 4413 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 4414 __ pop(ecx); | 4414 __ pop(ecx); |
| 4415 int additional_offset = | 4415 int additional_offset = |
| 4416 function_mode() == JS_FUNCTION_STUB_MODE ? kPointerSize : 0; | 4416 function_mode() == JS_FUNCTION_STUB_MODE ? kPointerSize : 0; |
| 4417 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset)); | 4417 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset)); |
| 4418 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack. | 4418 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack. |
| 4419 } | 4419 } |
| 4420 | 4420 |
| 4421 | 4421 |
| 4422 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { | 4422 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { |
| 4423 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); | 4423 EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister()); |
| 4424 VectorRawLoadStub stub(isolate(), state()); | 4424 LoadICStub stub(isolate(), state()); |
| 4425 stub.GenerateForTrampoline(masm); | 4425 stub.GenerateForTrampoline(masm); |
| 4426 } | 4426 } |
| 4427 | 4427 |
| 4428 | 4428 |
| 4429 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { | 4429 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { |
| 4430 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); | 4430 EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister()); |
| 4431 VectorRawKeyedLoadStub stub(isolate()); | 4431 KeyedLoadICStub stub(isolate()); |
| 4432 stub.GenerateForTrampoline(masm); | 4432 stub.GenerateForTrampoline(masm); |
| 4433 } | 4433 } |
| 4434 | 4434 |
| 4435 | 4435 |
| 4436 static void HandleArrayCases(MacroAssembler* masm, Register receiver, | 4436 static void HandleArrayCases(MacroAssembler* masm, Register receiver, |
| 4437 Register key, Register vector, Register slot, | 4437 Register key, Register vector, Register slot, |
| 4438 Register feedback, bool is_polymorphic, | 4438 Register feedback, bool is_polymorphic, |
| 4439 Label* miss) { | 4439 Label* miss) { |
| 4440 // feedback initially contains the feedback array | 4440 // feedback initially contains the feedback array |
| 4441 Label next, next_loop, prepare_next; | 4441 Label next, next_loop, prepare_next; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4538 __ bind(&compare_smi_map); | 4538 __ bind(&compare_smi_map); |
| 4539 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); | 4539 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); |
| 4540 __ j(not_equal, miss); | 4540 __ j(not_equal, miss); |
| 4541 __ mov(handler, FieldOperand(vector, slot, times_half_pointer_size, | 4541 __ mov(handler, FieldOperand(vector, slot, times_half_pointer_size, |
| 4542 FixedArray::kHeaderSize + kPointerSize)); | 4542 FixedArray::kHeaderSize + kPointerSize)); |
| 4543 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 4543 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); |
| 4544 __ jmp(handler); | 4544 __ jmp(handler); |
| 4545 } | 4545 } |
| 4546 | 4546 |
| 4547 | 4547 |
| 4548 void VectorRawLoadStub::Generate(MacroAssembler* masm) { | 4548 void LoadICStub::Generate(MacroAssembler* masm) { GenerateImpl(masm, false); } |
| 4549 GenerateImpl(masm, false); | |
| 4550 } | |
| 4551 | 4549 |
| 4552 | 4550 |
| 4553 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) { | 4551 void LoadICStub::GenerateForTrampoline(MacroAssembler* masm) { |
| 4554 GenerateImpl(masm, true); | 4552 GenerateImpl(masm, true); |
| 4555 } | 4553 } |
| 4556 | 4554 |
| 4557 | 4555 |
| 4558 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4556 void LoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
| 4559 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // edx | 4557 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // edx |
| 4560 Register name = VectorLoadICDescriptor::NameRegister(); // ecx | 4558 Register name = LoadWithVectorDescriptor::NameRegister(); // ecx |
| 4561 Register vector = VectorLoadICDescriptor::VectorRegister(); // ebx | 4559 Register vector = LoadWithVectorDescriptor::VectorRegister(); // ebx |
| 4562 Register slot = VectorLoadICDescriptor::SlotRegister(); // eax | 4560 Register slot = LoadWithVectorDescriptor::SlotRegister(); // eax |
| 4563 Register scratch = edi; | 4561 Register scratch = edi; |
| 4564 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | 4562 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, |
| 4565 FixedArray::kHeaderSize)); | 4563 FixedArray::kHeaderSize)); |
| 4566 | 4564 |
| 4567 // Is it a weak cell? | 4565 // Is it a weak cell? |
| 4568 Label try_array; | 4566 Label try_array; |
| 4569 Label not_array, smi_key, key_okay, miss; | 4567 Label not_array, smi_key, key_okay, miss; |
| 4570 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | 4568 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); |
| 4571 __ j(not_equal, &try_array); | 4569 __ j(not_equal, &try_array); |
| 4572 HandleMonomorphicCase(masm, receiver, name, vector, slot, scratch, &miss); | 4570 HandleMonomorphicCase(masm, receiver, name, vector, slot, scratch, &miss); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4587 masm->isolate()->stub_cache()->GenerateProbe( | 4585 masm->isolate()->stub_cache()->GenerateProbe( |
| 4588 masm, Code::LOAD_IC, code_flags, false, receiver, name, vector, scratch); | 4586 masm, Code::LOAD_IC, code_flags, false, receiver, name, vector, scratch); |
| 4589 __ pop(vector); | 4587 __ pop(vector); |
| 4590 __ pop(slot); | 4588 __ pop(slot); |
| 4591 | 4589 |
| 4592 __ bind(&miss); | 4590 __ bind(&miss); |
| 4593 LoadIC::GenerateMiss(masm); | 4591 LoadIC::GenerateMiss(masm); |
| 4594 } | 4592 } |
| 4595 | 4593 |
| 4596 | 4594 |
| 4597 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) { | 4595 void KeyedLoadICStub::Generate(MacroAssembler* masm) { |
| 4598 GenerateImpl(masm, false); | 4596 GenerateImpl(masm, false); |
| 4599 } | 4597 } |
| 4600 | 4598 |
| 4601 | 4599 |
| 4602 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) { | 4600 void KeyedLoadICStub::GenerateForTrampoline(MacroAssembler* masm) { |
| 4603 GenerateImpl(masm, true); | 4601 GenerateImpl(masm, true); |
| 4604 } | 4602 } |
| 4605 | 4603 |
| 4606 | 4604 |
| 4607 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4605 void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
| 4608 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // edx | 4606 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // edx |
| 4609 Register key = VectorLoadICDescriptor::NameRegister(); // ecx | 4607 Register key = LoadWithVectorDescriptor::NameRegister(); // ecx |
| 4610 Register vector = VectorLoadICDescriptor::VectorRegister(); // ebx | 4608 Register vector = LoadWithVectorDescriptor::VectorRegister(); // ebx |
| 4611 Register slot = VectorLoadICDescriptor::SlotRegister(); // eax | 4609 Register slot = LoadWithVectorDescriptor::SlotRegister(); // eax |
| 4612 Register feedback = edi; | 4610 Register feedback = edi; |
| 4613 __ mov(feedback, FieldOperand(vector, slot, times_half_pointer_size, | 4611 __ mov(feedback, FieldOperand(vector, slot, times_half_pointer_size, |
| 4614 FixedArray::kHeaderSize)); | 4612 FixedArray::kHeaderSize)); |
| 4615 // Is it a weak cell? | 4613 // Is it a weak cell? |
| 4616 Label try_array; | 4614 Label try_array; |
| 4617 Label not_array, smi_key, key_okay, miss; | 4615 Label not_array, smi_key, key_okay, miss; |
| 4618 __ CompareRoot(FieldOperand(feedback, 0), Heap::kWeakCellMapRootIndex); | 4616 __ CompareRoot(FieldOperand(feedback, 0), Heap::kWeakCellMapRootIndex); |
| 4619 __ j(not_equal, &try_array); | 4617 __ j(not_equal, &try_array); |
| 4620 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, &miss); | 4618 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, &miss); |
| 4621 | 4619 |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5425 ApiParameterOperand(2), kStackSpace, nullptr, | 5423 ApiParameterOperand(2), kStackSpace, nullptr, |
| 5426 Operand(ebp, 7 * kPointerSize), NULL); | 5424 Operand(ebp, 7 * kPointerSize), NULL); |
| 5427 } | 5425 } |
| 5428 | 5426 |
| 5429 | 5427 |
| 5430 #undef __ | 5428 #undef __ |
| 5431 | 5429 |
| 5432 } } // namespace v8::internal | 5430 } } // namespace v8::internal |
| 5433 | 5431 |
| 5434 #endif // V8_TARGET_ARCH_IA32 | 5432 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |