| 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 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 __ bind(&done); | 646 __ bind(&done); |
| 647 __ IncrementCounter(counters->math_pow(), 1); | 647 __ IncrementCounter(counters->math_pow(), 1); |
| 648 __ ret(0); | 648 __ ret(0); |
| 649 } | 649 } |
| 650 } | 650 } |
| 651 | 651 |
| 652 | 652 |
| 653 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { | 653 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { |
| 654 Label miss; | 654 Label miss; |
| 655 Register receiver = LoadDescriptor::ReceiverRegister(); | 655 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 656 if (FLAG_vector_ics) { | 656 // With careful management, we won't have to save slot and vector on |
| 657 // With careful management, we won't have to save slot and vector on | 657 // the stack. Simply handle the possibly missing case first. |
| 658 // the stack. Simply handle the possibly missing case first. | 658 // TODO(mvstanton): this code can be more efficient. |
| 659 // TODO(mvstanton): this code can be more efficient. | 659 __ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset), |
| 660 __ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset), | 660 Immediate(isolate()->factory()->the_hole_value())); |
| 661 Immediate(isolate()->factory()->the_hole_value())); | 661 __ j(equal, &miss); |
| 662 __ j(equal, &miss); | 662 __ TryGetFunctionPrototype(receiver, eax, ebx, &miss); |
| 663 __ TryGetFunctionPrototype(receiver, eax, ebx, &miss); | 663 __ ret(0); |
| 664 __ ret(0); | |
| 665 } else { | |
| 666 NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax, | |
| 667 ebx, &miss); | |
| 668 } | |
| 669 | 664 |
| 670 __ bind(&miss); | 665 __ bind(&miss); |
| 671 PropertyAccessCompiler::TailCallBuiltin( | 666 PropertyAccessCompiler::TailCallBuiltin( |
| 672 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); | 667 masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC)); |
| 673 } | 668 } |
| 674 | 669 |
| 675 | 670 |
| 676 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 671 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
| 677 // Return address is on the stack. | 672 // Return address is on the stack. |
| 678 Label slow; | 673 Label slow; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 706 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { | 701 void LoadIndexedStringStub::Generate(MacroAssembler* masm) { |
| 707 // Return address is on the stack. | 702 // Return address is on the stack. |
| 708 Label miss; | 703 Label miss; |
| 709 | 704 |
| 710 Register receiver = LoadDescriptor::ReceiverRegister(); | 705 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 711 Register index = LoadDescriptor::NameRegister(); | 706 Register index = LoadDescriptor::NameRegister(); |
| 712 Register scratch = edi; | 707 Register scratch = edi; |
| 713 DCHECK(!scratch.is(receiver) && !scratch.is(index)); | 708 DCHECK(!scratch.is(receiver) && !scratch.is(index)); |
| 714 Register result = eax; | 709 Register result = eax; |
| 715 DCHECK(!result.is(scratch)); | 710 DCHECK(!result.is(scratch)); |
| 716 DCHECK(!FLAG_vector_ics || | 711 DCHECK(!scratch.is(VectorLoadICDescriptor::VectorRegister()) && |
| 717 (!scratch.is(VectorLoadICDescriptor::VectorRegister()) && | 712 result.is(VectorLoadICDescriptor::SlotRegister())); |
| 718 result.is(VectorLoadICDescriptor::SlotRegister()))); | |
| 719 | 713 |
| 720 // StringCharAtGenerator doesn't use the result register until it's passed | 714 // StringCharAtGenerator doesn't use the result register until it's passed |
| 721 // 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 |
| 722 // when FLAG_vector_ics is true. | 716 // when FLAG_vector_ics is true. |
| 723 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, | 717 StringCharAtGenerator char_at_generator(receiver, index, scratch, result, |
| 724 &miss, // When not a string. | 718 &miss, // When not a string. |
| 725 &miss, // When not a number. | 719 &miss, // When not a number. |
| 726 &miss, // When index out of range. | 720 &miss, // When index out of range. |
| 727 STRING_INDEX_IS_ARRAY_INDEX, | 721 STRING_INDEX_IS_ARRAY_INDEX, |
| 728 RECEIVER_IS_STRING); | 722 RECEIVER_IS_STRING); |
| (...skipping 2238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2967 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase); | 2961 __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase); |
| 2968 | 2962 |
| 2969 // Index is not a smi. | 2963 // Index is not a smi. |
| 2970 __ bind(&index_not_smi_); | 2964 __ bind(&index_not_smi_); |
| 2971 // 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. |
| 2972 __ CheckMap(index_, | 2966 __ CheckMap(index_, |
| 2973 masm->isolate()->factory()->heap_number_map(), | 2967 masm->isolate()->factory()->heap_number_map(), |
| 2974 index_not_number_, | 2968 index_not_number_, |
| 2975 DONT_DO_SMI_CHECK); | 2969 DONT_DO_SMI_CHECK); |
| 2976 call_helper.BeforeCall(masm); | 2970 call_helper.BeforeCall(masm); |
| 2977 if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) { | 2971 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2978 __ push(VectorLoadICDescriptor::VectorRegister()); | 2972 __ push(VectorLoadICDescriptor::VectorRegister()); |
| 2979 __ push(VectorLoadICDescriptor::SlotRegister()); | 2973 __ push(VectorLoadICDescriptor::SlotRegister()); |
| 2980 } | 2974 } |
| 2981 __ push(object_); | 2975 __ push(object_); |
| 2982 __ push(index_); // Consumed by runtime conversion function. | 2976 __ push(index_); // Consumed by runtime conversion function. |
| 2983 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 2977 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
| 2984 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 2978 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); |
| 2985 } else { | 2979 } else { |
| 2986 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 2980 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
| 2987 // NumberToSmi discards numbers that are not exact integers. | 2981 // NumberToSmi discards numbers that are not exact integers. |
| 2988 __ CallRuntime(Runtime::kNumberToSmi, 1); | 2982 __ CallRuntime(Runtime::kNumberToSmi, 1); |
| 2989 } | 2983 } |
| 2990 if (!index_.is(eax)) { | 2984 if (!index_.is(eax)) { |
| 2991 // Save the conversion result before the pop instructions below | 2985 // Save the conversion result before the pop instructions below |
| 2992 // have a chance to overwrite it. | 2986 // have a chance to overwrite it. |
| 2993 __ mov(index_, eax); | 2987 __ mov(index_, eax); |
| 2994 } | 2988 } |
| 2995 __ pop(object_); | 2989 __ pop(object_); |
| 2996 if (FLAG_vector_ics && embed_mode == PART_OF_IC_HANDLER) { | 2990 if (embed_mode == PART_OF_IC_HANDLER) { |
| 2997 __ pop(VectorLoadICDescriptor::SlotRegister()); | 2991 __ pop(VectorLoadICDescriptor::SlotRegister()); |
| 2998 __ pop(VectorLoadICDescriptor::VectorRegister()); | 2992 __ pop(VectorLoadICDescriptor::VectorRegister()); |
| 2999 } | 2993 } |
| 3000 // Reload the instance type. | 2994 // Reload the instance type. |
| 3001 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 2995 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
| 3002 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 2996 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
| 3003 call_helper.AfterCall(masm); | 2997 call_helper.AfterCall(masm); |
| 3004 // 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. |
| 3005 STATIC_ASSERT(kSmiTag == 0); | 2999 STATIC_ASSERT(kSmiTag == 0); |
| 3006 __ JumpIfNotSmi(index_, index_out_of_range_); | 3000 __ JumpIfNotSmi(index_, index_out_of_range_); |
| (...skipping 2424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5431 ApiParameterOperand(2), kStackSpace, nullptr, | 5425 ApiParameterOperand(2), kStackSpace, nullptr, |
| 5432 Operand(ebp, 7 * kPointerSize), NULL); | 5426 Operand(ebp, 7 * kPointerSize), NULL); |
| 5433 } | 5427 } |
| 5434 | 5428 |
| 5435 | 5429 |
| 5436 #undef __ | 5430 #undef __ |
| 5437 | 5431 |
| 5438 } } // namespace v8::internal | 5432 } } // namespace v8::internal |
| 5439 | 5433 |
| 5440 #endif // V8_TARGET_ARCH_IA32 | 5434 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |