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 |