| 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_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { | 381 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { |
| 382 // Return address is on the stack. | 382 // Return address is on the stack. |
| 383 Label miss; | 383 Label miss; |
| 384 | 384 |
| 385 Register receiver = LoadDescriptor::ReceiverRegister(); | 385 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 386 Register index = LoadDescriptor::NameRegister(); | 386 Register index = LoadDescriptor::NameRegister(); |
| 387 Register scratch = edi; | 387 Register scratch = edi; |
| 388 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 388 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 389 Register result = eax; | 389 Register result = eax; |
| 390 DCHECK(!result.is(scratch)); | 390 DCHECK(!result.is(scratch)); |
| 391 DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) && | 391 DCHECK(!scratch.is(LoadWithVectorDescriptor::VectorRegister()) && |
| 392 result.is(VectorLoadICDescriptor::SlotRegister())); | 392 result.is(LoadDescriptor::SlotRegister())); |
| 393 | 393 |
| 394 // StringCharAtGenerator doesn't use the result register until it's passed | 394 // StringCharAtGenerator doesn't use the result register until it's passed |
| 395 // the different miss possibilities. If it did, we would have a conflict | 395 // the different miss possibilities. If it did, we would have a conflict |
| 396 // when FLAG_vector_ics is true. | 396 // when FLAG_vector_ics is true. |
| 397 | 397 |
| 398 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 398 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
| 399 &miss, // When not a string. | 399 &miss, // When not a string. |
| 400 &miss, // When not a number. | 400 &miss, // When not a number. |
| 401 &miss, // When index out of range. | 401 &miss, // When index out of range. |
| 402 STRING_INDEX_IS_ARRAY_INDEX, | 402 STRING_INDEX_IS_ARRAY_INDEX, |
| (...skipping 2249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2652 | 2652 |
| 2653 // Index is not a smi. | 2653 // Index is not a smi. |
| 2654 __ bind(&index_not_smi_); | 2654 __ bind(&index_not_smi_); |
| 2655 // If index is a heap number, try converting it to an integer. | 2655 // If index is a heap number, try converting it to an integer. |
| 2656 __ CheckMap(index_, | 2656 __ CheckMap(index_, |
| 2657 masm->isolate()->factory()->heap_number_map(), | 2657 masm->isolate()->factory()->heap_number_map(), |
| 2658 index_not_number_, | 2658 index_not_number_, |
| 2659 DONT_DO_SMI_CHECK); | 2659 DONT_DO_SMI_CHECK); |
| 2660 call_helper.BeforeCall(masm); | 2660 call_helper.BeforeCall(masm); |
| 2661 if (embed_mode == PART_OF_IC_HANDLER) { | 2661 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2662 __ push(VectorLoadICDescriptor::VectorRegister()); | 2662 __ push(LoadWithVectorDescriptor::VectorRegister()); |
| 2663 __ push(VectorLoadICDescriptor::SlotRegister()); | 2663 __ push(LoadDescriptor::SlotRegister()); |
| 2664 } | 2664 } |
| 2665 __ push(object_); | 2665 __ push(object_); |
| 2666 __ push(index_); // Consumed by runtime conversion function. | 2666 __ push(index_); // Consumed by runtime conversion function. |
| 2667 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 2667 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
| 2668 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 2668 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
| 2669 } else { | 2669 } else { |
| 2670 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 2670 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
| 2671 // NumberToSmi discards numbers that are not exact integers. | 2671 // NumberToSmi discards numbers that are not exact integers. |
| 2672 __ CallRuntime(Runtime::kNumberToSmi, 1); | 2672 __ CallRuntime(Runtime::kNumberToSmi, 1); |
| 2673 } | 2673 } |
| 2674 if (!index_.is(eax)) { | 2674 if (!index_.is(eax)) { |
| 2675 // Save the conversion result before the pop instructions below | 2675 // Save the conversion result before the pop instructions below |
| 2676 // have a chance to overwrite it. | 2676 // have a chance to overwrite it. |
| 2677 __ mov(index_, eax); | 2677 __ mov(index_, eax); |
| 2678 } | 2678 } |
| 2679 __ pop(object_); | 2679 __ pop(object_); |
| 2680 if (embed_mode == PART_OF_IC_HANDLER) { | 2680 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2681 __ pop(VectorLoadICDescriptor::SlotRegister()); | 2681 __ pop(LoadDescriptor::SlotRegister()); |
| 2682 __ pop(VectorLoadICDescriptor::VectorRegister()); | 2682 __ pop(LoadWithVectorDescriptor::VectorRegister()); |
| 2683 } | 2683 } |
| 2684 // Reload the instance type. | 2684 // Reload the instance type. |
| 2685 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 2685 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
| 2686 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 2686 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
| 2687 call_helper.AfterCall(masm); | 2687 call_helper.AfterCall(masm); |
| 2688 // If index is still not a smi, it must be out of range. | 2688 // If index is still not a smi, it must be out of range. |
| 2689 STATIC_ASSERT(kSmiTag == 0); | 2689 STATIC_ASSERT(kSmiTag == 0); |
| 2690 __ JumpIfNotSmi(index_, index_out_of_range_); | 2690 __ JumpIfNotSmi(index_, index_out_of_range_); |
| 2691 // Otherwise, return to the fast path. | 2691 // Otherwise, return to the fast path. |
| 2692 __ jmp(&got_smi_index_); | 2692 __ jmp(&got_smi_index_); |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4073 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 4073 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
| 4074 __ pop(ecx); | 4074 __ pop(ecx); |
| 4075 int additional_offset = | 4075 int additional_offset = |
| 4076 function_mode() == JS_FUNCTION_STUB_MODE ? kPointerSize : 0; | 4076 function_mode() == JS_FUNCTION_STUB_MODE ? kPointerSize : 0; |
| 4077 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset)); | 4077 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset)); |
| 4078 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack. | 4078 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack. |
| 4079 } | 4079 } |
| 4080 | 4080 |
| 4081 | 4081 |
| 4082 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { | 4082 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { |
| 4083 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); | 4083 EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister()); |
| 4084 VectorRawLoadStub stub(isolate(), state()); | 4084 LoadICStub stub(isolate(), state()); |
| 4085 stub.GenerateForTrampoline(masm); | 4085 stub.GenerateForTrampoline(masm); |
| 4086 } | 4086 } |
| 4087 | 4087 |
| 4088 | 4088 |
| 4089 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { | 4089 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { |
| 4090 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); | 4090 EmitLoadTypeFeedbackVector(masm, LoadWithVectorDescriptor::VectorRegister()); |
| 4091 VectorRawKeyedLoadStub stub(isolate()); | 4091 KeyedLoadICStub stub(isolate()); |
| 4092 stub.GenerateForTrampoline(masm); | 4092 stub.GenerateForTrampoline(masm); |
| 4093 } | 4093 } |
| 4094 | 4094 |
| 4095 | 4095 |
| 4096 static void HandleArrayCases(MacroAssembler* masm, Register receiver, | 4096 static void HandleArrayCases(MacroAssembler* masm, Register receiver, |
| 4097 Register key, Register vector, Register slot, | 4097 Register key, Register vector, Register slot, |
| 4098 Register feedback, bool is_polymorphic, | 4098 Register feedback, bool is_polymorphic, |
| 4099 Label* miss) { | 4099 Label* miss) { |
| 4100 // feedback initially contains the feedback array | 4100 // feedback initially contains the feedback array |
| 4101 Label next, next_loop, prepare_next; | 4101 Label next, next_loop, prepare_next; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4198 __ bind(&compare_smi_map); | 4198 __ bind(&compare_smi_map); |
| 4199 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); | 4199 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); |
| 4200 __ j(not_equal, miss); | 4200 __ j(not_equal, miss); |
| 4201 __ mov(handler, FieldOperand(vector, slot, times_half_pointer_size, | 4201 __ mov(handler, FieldOperand(vector, slot, times_half_pointer_size, |
| 4202 FixedArray::kHeaderSize + kPointerSize)); | 4202 FixedArray::kHeaderSize + kPointerSize)); |
| 4203 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); | 4203 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); |
| 4204 __ jmp(handler); | 4204 __ jmp(handler); |
| 4205 } | 4205 } |
| 4206 | 4206 |
| 4207 | 4207 |
| 4208 void VectorRawLoadStub::Generate(MacroAssembler* masm) { | 4208 void LoadICStub::Generate(MacroAssembler* masm) { GenerateImpl(masm, false); } |
| 4209 GenerateImpl(masm, false); | |
| 4210 } | |
| 4211 | 4209 |
| 4212 | 4210 |
| 4213 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) { | 4211 void LoadICStub::GenerateForTrampoline(MacroAssembler* masm) { |
| 4214 GenerateImpl(masm, true); | 4212 GenerateImpl(masm, true); |
| 4215 } | 4213 } |
| 4216 | 4214 |
| 4217 | 4215 |
| 4218 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4216 void LoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
| 4219 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // edx | 4217 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // edx |
| 4220 Register name = VectorLoadICDescriptor::NameRegister(); // ecx | 4218 Register name = LoadWithVectorDescriptor::NameRegister(); // ecx |
| 4221 Register vector = VectorLoadICDescriptor::VectorRegister(); // ebx | 4219 Register vector = LoadWithVectorDescriptor::VectorRegister(); // ebx |
| 4222 Register slot = VectorLoadICDescriptor::SlotRegister(); // eax | 4220 Register slot = LoadWithVectorDescriptor::SlotRegister(); // eax |
| 4223 Register scratch = edi; | 4221 Register scratch = edi; |
| 4224 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | 4222 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, |
| 4225 FixedArray::kHeaderSize)); | 4223 FixedArray::kHeaderSize)); |
| 4226 | 4224 |
| 4227 // Is it a weak cell? | 4225 // Is it a weak cell? |
| 4228 Label try_array; | 4226 Label try_array; |
| 4229 Label not_array, smi_key, key_okay, miss; | 4227 Label not_array, smi_key, key_okay, miss; |
| 4230 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | 4228 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); |
| 4231 __ j(not_equal, &try_array); | 4229 __ j(not_equal, &try_array); |
| 4232 HandleMonomorphicCase(masm, receiver, name, vector, slot, scratch, &miss); | 4230 HandleMonomorphicCase(masm, receiver, name, vector, slot, scratch, &miss); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4247 masm->isolate()->stub_cache()->GenerateProbe( | 4245 masm->isolate()->stub_cache()->GenerateProbe( |
| 4248 masm, Code::LOAD_IC, code_flags, false, receiver, name, vector, scratch); | 4246 masm, Code::LOAD_IC, code_flags, false, receiver, name, vector, scratch); |
| 4249 __ pop(vector); | 4247 __ pop(vector); |
| 4250 __ pop(slot); | 4248 __ pop(slot); |
| 4251 | 4249 |
| 4252 __ bind(&miss); | 4250 __ bind(&miss); |
| 4253 LoadIC::GenerateMiss(masm); | 4251 LoadIC::GenerateMiss(masm); |
| 4254 } | 4252 } |
| 4255 | 4253 |
| 4256 | 4254 |
| 4257 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) { | 4255 void KeyedLoadICStub::Generate(MacroAssembler* masm) { |
| 4258 GenerateImpl(masm, false); | 4256 GenerateImpl(masm, false); |
| 4259 } | 4257 } |
| 4260 | 4258 |
| 4261 | 4259 |
| 4262 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) { | 4260 void KeyedLoadICStub::GenerateForTrampoline(MacroAssembler* masm) { |
| 4263 GenerateImpl(masm, true); | 4261 GenerateImpl(masm, true); |
| 4264 } | 4262 } |
| 4265 | 4263 |
| 4266 | 4264 |
| 4267 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 4265 void KeyedLoadICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
| 4268 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // edx | 4266 Register receiver = LoadWithVectorDescriptor::ReceiverRegister(); // edx |
| 4269 Register key = VectorLoadICDescriptor::NameRegister(); // ecx | 4267 Register key = LoadWithVectorDescriptor::NameRegister(); // ecx |
| 4270 Register vector = VectorLoadICDescriptor::VectorRegister(); // ebx | 4268 Register vector = LoadWithVectorDescriptor::VectorRegister(); // ebx |
| 4271 Register slot = VectorLoadICDescriptor::SlotRegister(); // eax | 4269 Register slot = LoadWithVectorDescriptor::SlotRegister(); // eax |
| 4272 Register feedback = edi; | 4270 Register feedback = edi; |
| 4273 __ mov(feedback, FieldOperand(vector, slot, times_half_pointer_size, | 4271 __ mov(feedback, FieldOperand(vector, slot, times_half_pointer_size, |
| 4274 FixedArray::kHeaderSize)); | 4272 FixedArray::kHeaderSize)); |
| 4275 // Is it a weak cell? | 4273 // Is it a weak cell? |
| 4276 Label try_array; | 4274 Label try_array; |
| 4277 Label not_array, smi_key, key_okay, miss; | 4275 Label not_array, smi_key, key_okay, miss; |
| 4278 __ CompareRoot(FieldOperand(feedback, 0), Heap::kWeakCellMapRootIndex); | 4276 __ CompareRoot(FieldOperand(feedback, 0), Heap::kWeakCellMapRootIndex); |
| 4279 __ j(not_equal, &try_array); | 4277 __ j(not_equal, &try_array); |
| 4280 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, &miss); | 4278 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, &miss); |
| 4281 | 4279 |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5085 ApiParameterOperand(2), kStackSpace, nullptr, | 5083 ApiParameterOperand(2), kStackSpace, nullptr, |
| 5086 Operand(ebp, 7 * kPointerSize), NULL); | 5084 Operand(ebp, 7 * kPointerSize), NULL); |
| 5087 } | 5085 } |
| 5088 | 5086 |
| 5089 | 5087 |
| 5090 #undef __ | 5088 #undef __ |
| 5091 | 5089 |
| 5092 } } // namespace v8::internal | 5090 } } // namespace v8::internal |
| 5093 | 5091 |
| 5094 #endif // V8_TARGET_ARCH_X87 | 5092 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |