OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 // Helper function used to check that the dictionary doesn't contain | 84 // Helper function used to check that the dictionary doesn't contain |
85 // the property. This function may return false negatives, so miss_label | 85 // the property. This function may return false negatives, so miss_label |
86 // must always call a backup property check that is complete. | 86 // must always call a backup property check that is complete. |
87 // This function is safe to call if the receiver has fast properties. | 87 // This function is safe to call if the receiver has fast properties. |
88 // Name must be a symbol and receiver must be a heap object. | 88 // Name must be a symbol and receiver must be a heap object. |
89 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 89 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
90 Label* miss_label, | 90 Label* miss_label, |
91 Register receiver, | 91 Register receiver, |
92 String* name, | 92 String* name, |
93 Register r0, | 93 Register r0, |
94 Register extra) { | 94 Register r1) { |
95 ASSERT(name->IsSymbol()); | 95 ASSERT(name->IsSymbol()); |
96 __ IncrementCounter(&Counters::negative_lookups, 1); | 96 __ IncrementCounter(&Counters::negative_lookups, 1); |
97 __ IncrementCounter(&Counters::negative_lookups_miss, 1); | 97 __ IncrementCounter(&Counters::negative_lookups_miss, 1); |
98 | 98 |
99 Label done; | 99 Label done; |
100 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); | 100 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
101 | 101 |
102 const int kInterceptorOrAccessCheckNeededMask = | 102 const int kInterceptorOrAccessCheckNeededMask = |
103 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 103 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
104 | 104 |
(...skipping 28 matching lines...) Expand all Loading... |
133 StringDictionary::kElementsStartIndex * kPointerSize; | 133 StringDictionary::kElementsStartIndex * kPointerSize; |
134 | 134 |
135 // If names of slots in range from 1 to kProbes - 1 for the hash value are | 135 // If names of slots in range from 1 to kProbes - 1 for the hash value are |
136 // not equal to the name and kProbes-th slot is not used (its name is the | 136 // not equal to the name and kProbes-th slot is not used (its name is the |
137 // undefined value), it guarantees the hash table doesn't contain the | 137 // undefined value), it guarantees the hash table doesn't contain the |
138 // property. It's true even if some slots represent deleted properties | 138 // property. It's true even if some slots represent deleted properties |
139 // (their names are the null value). | 139 // (their names are the null value). |
140 for (int i = 0; i < kProbes; i++) { | 140 for (int i = 0; i < kProbes; i++) { |
141 // r0 points to properties hash. | 141 // r0 points to properties hash. |
142 // Compute the masked index: (hash + i + i * i) & mask. | 142 // Compute the masked index: (hash + i + i * i) & mask. |
143 if (extra.is(no_reg)) { | 143 Register index = r1; |
144 __ push(receiver); | |
145 } | |
146 Register index = extra.is(no_reg) ? receiver : extra; | |
147 // Capacity is smi 2^n. | 144 // Capacity is smi 2^n. |
148 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); | 145 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset)); |
149 __ decl(index); | 146 __ decl(index); |
150 __ and_(index, | 147 __ and_(index, |
151 Immediate(name->Hash() + StringDictionary::GetProbeOffset(i))); | 148 Immediate(name->Hash() + StringDictionary::GetProbeOffset(i))); |
152 | 149 |
153 // Scale the index by multiplying by the entry size. | 150 // Scale the index by multiplying by the entry size. |
154 ASSERT(StringDictionary::kEntrySize == 3); | 151 ASSERT(StringDictionary::kEntrySize == 3); |
155 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. | 152 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3. |
156 | 153 |
157 Register entity_name = extra.is(no_reg) ? properties : extra; | 154 Register entity_name = r1; |
158 // Having undefined at this place means the name is not contained. | 155 // Having undefined at this place means the name is not contained. |
159 ASSERT_EQ(kSmiTagSize, 1); | 156 ASSERT_EQ(kSmiTagSize, 1); |
160 __ movq(entity_name, Operand(properties, index, times_pointer_size, | 157 __ movq(entity_name, Operand(properties, index, times_pointer_size, |
161 kElementsStartOffset - kHeapObjectTag)); | 158 kElementsStartOffset - kHeapObjectTag)); |
162 __ Cmp(entity_name, Factory::undefined_value()); | 159 __ Cmp(entity_name, Factory::undefined_value()); |
163 if (extra.is(no_reg)) { | |
164 // 'receiver' shares a register with 'entity_name'. | |
165 __ pop(receiver); | |
166 } | |
167 // __ jmp(miss_label); | 160 // __ jmp(miss_label); |
168 if (i != kProbes - 1) { | 161 if (i != kProbes - 1) { |
169 __ j(equal, &done); | 162 __ j(equal, &done); |
170 | 163 |
171 // Stop if found the property. | 164 // Stop if found the property. |
172 __ Cmp(entity_name, Handle<String>(name)); | 165 __ Cmp(entity_name, Handle<String>(name)); |
173 __ j(equal, miss_label); | 166 __ j(equal, miss_label); |
174 | |
175 if (extra.is(no_reg)) { | |
176 // Restore the properties if their register was occupied by the name. | |
177 __ movq(properties, | |
178 FieldOperand(receiver, JSObject::kPropertiesOffset)); | |
179 } | |
180 } else { | 167 } else { |
181 // Give up probing if still not found the undefined value. | 168 // Give up probing if still not found the undefined value. |
182 __ j(not_equal, miss_label); | 169 __ j(not_equal, miss_label); |
183 } | 170 } |
184 } | 171 } |
185 | 172 |
186 __ bind(&done); | 173 __ bind(&done); |
187 __ DecrementCounter(&Counters::negative_lookups_miss, 1); | 174 __ DecrementCounter(&Counters::negative_lookups_miss, 1); |
188 } | 175 } |
189 | 176 |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 name_(name) {} | 584 name_(name) {} |
598 | 585 |
599 void Compile(MacroAssembler* masm, | 586 void Compile(MacroAssembler* masm, |
600 JSObject* object, | 587 JSObject* object, |
601 JSObject* holder, | 588 JSObject* holder, |
602 String* name, | 589 String* name, |
603 LookupResult* lookup, | 590 LookupResult* lookup, |
604 Register receiver, | 591 Register receiver, |
605 Register scratch1, | 592 Register scratch1, |
606 Register scratch2, | 593 Register scratch2, |
| 594 Register scratch3, |
607 Label* miss) { | 595 Label* miss) { |
608 ASSERT(holder->HasNamedInterceptor()); | 596 ASSERT(holder->HasNamedInterceptor()); |
609 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 597 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
610 | 598 |
611 // Check that the receiver isn't a smi. | 599 // Check that the receiver isn't a smi. |
612 __ JumpIfSmi(receiver, miss); | 600 __ JumpIfSmi(receiver, miss); |
613 | 601 |
614 CallOptimization optimization(lookup); | 602 CallOptimization optimization(lookup); |
615 | 603 |
616 if (optimization.is_constant_call()) { | 604 if (optimization.is_constant_call()) { |
617 CompileCacheable(masm, | 605 CompileCacheable(masm, |
618 object, | 606 object, |
619 receiver, | 607 receiver, |
620 scratch1, | 608 scratch1, |
621 scratch2, | 609 scratch2, |
| 610 scratch3, |
622 holder, | 611 holder, |
623 lookup, | 612 lookup, |
624 name, | 613 name, |
625 optimization, | 614 optimization, |
626 miss); | 615 miss); |
627 } else { | 616 } else { |
628 CompileRegular(masm, | 617 CompileRegular(masm, |
629 object, | 618 object, |
630 receiver, | 619 receiver, |
631 scratch1, | 620 scratch1, |
632 scratch2, | 621 scratch2, |
| 622 scratch3, |
633 name, | 623 name, |
634 holder, | 624 holder, |
635 miss); | 625 miss); |
636 } | 626 } |
637 } | 627 } |
638 | 628 |
639 private: | 629 private: |
640 void CompileCacheable(MacroAssembler* masm, | 630 void CompileCacheable(MacroAssembler* masm, |
641 JSObject* object, | 631 JSObject* object, |
642 Register receiver, | 632 Register receiver, |
643 Register scratch1, | 633 Register scratch1, |
644 Register scratch2, | 634 Register scratch2, |
| 635 Register scratch3, |
645 JSObject* interceptor_holder, | 636 JSObject* interceptor_holder, |
646 LookupResult* lookup, | 637 LookupResult* lookup, |
647 String* name, | 638 String* name, |
648 const CallOptimization& optimization, | 639 const CallOptimization& optimization, |
649 Label* miss_label) { | 640 Label* miss_label) { |
650 ASSERT(optimization.is_constant_call()); | 641 ASSERT(optimization.is_constant_call()); |
651 ASSERT(!lookup->holder()->IsGlobalObject()); | 642 ASSERT(!lookup->holder()->IsGlobalObject()); |
652 | 643 |
653 int depth1 = kInvalidProtoDepth; | 644 int depth1 = kInvalidProtoDepth; |
654 int depth2 = kInvalidProtoDepth; | 645 int depth2 = kInvalidProtoDepth; |
(...skipping 19 matching lines...) Expand all Loading... |
674 ReserveSpaceForFastApiCall(masm, scratch1); | 665 ReserveSpaceForFastApiCall(masm, scratch1); |
675 } | 666 } |
676 | 667 |
677 // Check that the maps from receiver to interceptor's holder | 668 // Check that the maps from receiver to interceptor's holder |
678 // haven't changed and thus we can invoke interceptor. | 669 // haven't changed and thus we can invoke interceptor. |
679 Label miss_cleanup; | 670 Label miss_cleanup; |
680 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; | 671 Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; |
681 Register holder = | 672 Register holder = |
682 stub_compiler_->CheckPrototypes(object, receiver, | 673 stub_compiler_->CheckPrototypes(object, receiver, |
683 interceptor_holder, scratch1, | 674 interceptor_holder, scratch1, |
684 scratch2, name, depth1, miss); | 675 scratch2, scratch3, name, depth1, miss); |
685 | 676 |
686 // Invoke an interceptor and if it provides a value, | 677 // Invoke an interceptor and if it provides a value, |
687 // branch to |regular_invoke|. | 678 // branch to |regular_invoke|. |
688 Label regular_invoke; | 679 Label regular_invoke; |
689 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, | 680 LoadWithInterceptor(masm, receiver, holder, interceptor_holder, |
690 ®ular_invoke); | 681 ®ular_invoke); |
691 | 682 |
692 // Interceptor returned nothing for this property. Try to use cached | 683 // Interceptor returned nothing for this property. Try to use cached |
693 // constant function. | 684 // constant function. |
694 | 685 |
695 // Check that the maps from interceptor's holder to constant function's | 686 // Check that the maps from interceptor's holder to constant function's |
696 // holder haven't changed and thus we can use cached constant function. | 687 // holder haven't changed and thus we can use cached constant function. |
697 if (interceptor_holder != lookup->holder()) { | 688 if (interceptor_holder != lookup->holder()) { |
698 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, | 689 stub_compiler_->CheckPrototypes(interceptor_holder, receiver, |
699 lookup->holder(), scratch1, | 690 lookup->holder(), scratch1, |
700 scratch2, name, depth2, miss); | 691 scratch2, scratch3, name, depth2, miss); |
701 } else { | 692 } else { |
702 // CheckPrototypes has a side effect of fetching a 'holder' | 693 // CheckPrototypes has a side effect of fetching a 'holder' |
703 // for API (object which is instanceof for the signature). It's | 694 // for API (object which is instanceof for the signature). It's |
704 // safe to omit it here, as if present, it should be fetched | 695 // safe to omit it here, as if present, it should be fetched |
705 // by the previous CheckPrototypes. | 696 // by the previous CheckPrototypes. |
706 ASSERT(depth2 == kInvalidProtoDepth); | 697 ASSERT(depth2 == kInvalidProtoDepth); |
707 } | 698 } |
708 | 699 |
709 // Invoke function. | 700 // Invoke function. |
710 if (can_do_fast_api_call) { | 701 if (can_do_fast_api_call) { |
(...skipping 15 matching lines...) Expand all Loading... |
726 if (can_do_fast_api_call) { | 717 if (can_do_fast_api_call) { |
727 FreeSpaceForFastApiCall(masm, scratch1); | 718 FreeSpaceForFastApiCall(masm, scratch1); |
728 } | 719 } |
729 } | 720 } |
730 | 721 |
731 void CompileRegular(MacroAssembler* masm, | 722 void CompileRegular(MacroAssembler* masm, |
732 JSObject* object, | 723 JSObject* object, |
733 Register receiver, | 724 Register receiver, |
734 Register scratch1, | 725 Register scratch1, |
735 Register scratch2, | 726 Register scratch2, |
| 727 Register scratch3, |
736 String* name, | 728 String* name, |
737 JSObject* interceptor_holder, | 729 JSObject* interceptor_holder, |
738 Label* miss_label) { | 730 Label* miss_label) { |
739 Register holder = | 731 Register holder = |
740 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 732 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
741 scratch1, scratch2, name, | 733 scratch1, scratch2, scratch3, name, |
742 miss_label); | 734 miss_label); |
743 | 735 |
744 __ EnterInternalFrame(); | 736 __ EnterInternalFrame(); |
745 // Save the name_ register across the call. | 737 // Save the name_ register across the call. |
746 __ push(name_); | 738 __ push(name_); |
747 | 739 |
748 PushInterceptorArguments(masm, | 740 PushInterceptorArguments(masm, |
749 receiver, | 741 receiver, |
750 holder, | 742 holder, |
751 name_, | 743 name_, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 JSObject::cast(object), holder); | 876 JSObject::cast(object), holder); |
885 } | 877 } |
886 | 878 |
887 if (depth != kInvalidProtoDepth) { | 879 if (depth != kInvalidProtoDepth) { |
888 __ IncrementCounter(&Counters::call_const_fast_api, 1); | 880 __ IncrementCounter(&Counters::call_const_fast_api, 1); |
889 ReserveSpaceForFastApiCall(masm(), rax); | 881 ReserveSpaceForFastApiCall(masm(), rax); |
890 } | 882 } |
891 | 883 |
892 // Check that the maps haven't changed. | 884 // Check that the maps haven't changed. |
893 CheckPrototypes(JSObject::cast(object), rdx, holder, | 885 CheckPrototypes(JSObject::cast(object), rdx, holder, |
894 rbx, rax, name, depth, &miss, rdi); | 886 rbx, rax, rdi, name, depth, &miss); |
895 | 887 |
896 // Patch the receiver on the stack with the global proxy if | 888 // Patch the receiver on the stack with the global proxy if |
897 // necessary. | 889 // necessary. |
898 if (object->IsGlobalObject()) { | 890 if (object->IsGlobalObject()) { |
899 ASSERT(depth == kInvalidProtoDepth); | 891 ASSERT(depth == kInvalidProtoDepth); |
900 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 892 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
901 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 893 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
902 } | 894 } |
903 break; | 895 break; |
904 | 896 |
905 case STRING_CHECK: | 897 case STRING_CHECK: |
906 if (!function->IsBuiltin()) { | 898 if (!function->IsBuiltin()) { |
907 // Calling non-builtins with a value as receiver requires boxing. | 899 // Calling non-builtins with a value as receiver requires boxing. |
908 __ jmp(&miss); | 900 __ jmp(&miss); |
909 } else { | 901 } else { |
910 // Check that the object is a two-byte string or a symbol. | 902 // Check that the object is a two-byte string or a symbol. |
911 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); | 903 __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax); |
912 __ j(above_equal, &miss); | 904 __ j(above_equal, &miss); |
913 // Check that the maps starting from the prototype haven't changed. | 905 // Check that the maps starting from the prototype haven't changed. |
914 GenerateDirectLoadGlobalFunctionPrototype( | 906 GenerateDirectLoadGlobalFunctionPrototype( |
915 masm(), Context::STRING_FUNCTION_INDEX, rax); | 907 masm(), Context::STRING_FUNCTION_INDEX, rax); |
916 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 908 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
917 rbx, rdx, name, &miss, rdi); | 909 rbx, rdx, rdi, name, &miss); |
918 } | 910 } |
919 break; | 911 break; |
920 | 912 |
921 case NUMBER_CHECK: { | 913 case NUMBER_CHECK: { |
922 if (!function->IsBuiltin()) { | 914 if (!function->IsBuiltin()) { |
923 // Calling non-builtins with a value as receiver requires boxing. | 915 // Calling non-builtins with a value as receiver requires boxing. |
924 __ jmp(&miss); | 916 __ jmp(&miss); |
925 } else { | 917 } else { |
926 Label fast; | 918 Label fast; |
927 // Check that the object is a smi or a heap number. | 919 // Check that the object is a smi or a heap number. |
928 __ JumpIfSmi(rdx, &fast); | 920 __ JumpIfSmi(rdx, &fast); |
929 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); | 921 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax); |
930 __ j(not_equal, &miss); | 922 __ j(not_equal, &miss); |
931 __ bind(&fast); | 923 __ bind(&fast); |
932 // Check that the maps starting from the prototype haven't changed. | 924 // Check that the maps starting from the prototype haven't changed. |
933 GenerateDirectLoadGlobalFunctionPrototype( | 925 GenerateDirectLoadGlobalFunctionPrototype( |
934 masm(), Context::NUMBER_FUNCTION_INDEX, rax); | 926 masm(), Context::NUMBER_FUNCTION_INDEX, rax); |
935 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 927 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
936 rbx, rdx, name, &miss, rdi); | 928 rbx, rdx, rdi, name, &miss); |
937 } | 929 } |
938 break; | 930 break; |
939 } | 931 } |
940 | 932 |
941 case BOOLEAN_CHECK: { | 933 case BOOLEAN_CHECK: { |
942 if (!function->IsBuiltin()) { | 934 if (!function->IsBuiltin()) { |
943 // Calling non-builtins with a value as receiver requires boxing. | 935 // Calling non-builtins with a value as receiver requires boxing. |
944 __ jmp(&miss); | 936 __ jmp(&miss); |
945 } else { | 937 } else { |
946 Label fast; | 938 Label fast; |
947 // Check that the object is a boolean. | 939 // Check that the object is a boolean. |
948 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); | 940 __ CompareRoot(rdx, Heap::kTrueValueRootIndex); |
949 __ j(equal, &fast); | 941 __ j(equal, &fast); |
950 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); | 942 __ CompareRoot(rdx, Heap::kFalseValueRootIndex); |
951 __ j(not_equal, &miss); | 943 __ j(not_equal, &miss); |
952 __ bind(&fast); | 944 __ bind(&fast); |
953 // Check that the maps starting from the prototype haven't changed. | 945 // Check that the maps starting from the prototype haven't changed. |
954 GenerateDirectLoadGlobalFunctionPrototype( | 946 GenerateDirectLoadGlobalFunctionPrototype( |
955 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax); | 947 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax); |
956 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, | 948 CheckPrototypes(JSObject::cast(object->GetPrototype()), rax, holder, |
957 rbx, rdx, name, &miss, rdi); | 949 rbx, rdx, rdi, name, &miss); |
958 } | 950 } |
959 break; | 951 break; |
960 } | 952 } |
961 | 953 |
962 default: | 954 default: |
963 UNREACHABLE(); | 955 UNREACHABLE(); |
964 } | 956 } |
965 | 957 |
966 if (depth != kInvalidProtoDepth) { | 958 if (depth != kInvalidProtoDepth) { |
967 GenerateFastApiCall(masm(), optimization, argc); | 959 GenerateFastApiCall(masm(), optimization, argc); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 GenerateNameCheck(name, &miss); | 994 GenerateNameCheck(name, &miss); |
1003 | 995 |
1004 // Get the receiver from the stack. | 996 // Get the receiver from the stack. |
1005 const int argc = arguments().immediate(); | 997 const int argc = arguments().immediate(); |
1006 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 998 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1007 | 999 |
1008 // Check that the receiver isn't a smi. | 1000 // Check that the receiver isn't a smi. |
1009 __ JumpIfSmi(rdx, &miss); | 1001 __ JumpIfSmi(rdx, &miss); |
1010 | 1002 |
1011 // Do the right check and compute the holder register. | 1003 // Do the right check and compute the holder register. |
1012 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, | 1004 Register reg = CheckPrototypes(object, rdx, holder, rbx, rax, rdi, |
1013 name, &miss, rdi); | 1005 name, &miss); |
1014 | 1006 |
1015 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index); | 1007 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index); |
1016 | 1008 |
1017 // Check that the function really is a function. | 1009 // Check that the function really is a function. |
1018 __ JumpIfSmi(rdi, &miss); | 1010 __ JumpIfSmi(rdi, &miss); |
1019 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); | 1011 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); |
1020 __ j(not_equal, &miss); | 1012 __ j(not_equal, &miss); |
1021 | 1013 |
1022 // Patch the receiver on the stack with the global proxy if | 1014 // Patch the receiver on the stack with the global proxy if |
1023 // necessary. | 1015 // necessary. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1066 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1058 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1067 | 1059 |
1068 // Check that the receiver isn't a smi. | 1060 // Check that the receiver isn't a smi. |
1069 __ JumpIfSmi(rdx, &miss); | 1061 __ JumpIfSmi(rdx, &miss); |
1070 | 1062 |
1071 CheckPrototypes(JSObject::cast(object), | 1063 CheckPrototypes(JSObject::cast(object), |
1072 rdx, | 1064 rdx, |
1073 holder, | 1065 holder, |
1074 rbx, | 1066 rbx, |
1075 rax, | 1067 rax, |
| 1068 rdi, |
1076 name, | 1069 name, |
1077 &miss, | 1070 &miss); |
1078 rdi); | |
1079 | 1071 |
1080 if (argc == 0) { | 1072 if (argc == 0) { |
1081 // Noop, return the length. | 1073 // Noop, return the length. |
1082 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); | 1074 __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); |
1083 __ ret((argc + 1) * kPointerSize); | 1075 __ ret((argc + 1) * kPointerSize); |
1084 } else { | 1076 } else { |
1085 // Get the elements array of the object. | 1077 // Get the elements array of the object. |
1086 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); | 1078 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); |
1087 | 1079 |
1088 // Check that the elements are in fast mode (not dictionary). | 1080 // Check that the elements are in fast mode (not dictionary). |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 | 1213 |
1222 // Get the receiver from the stack. | 1214 // Get the receiver from the stack. |
1223 const int argc = arguments().immediate(); | 1215 const int argc = arguments().immediate(); |
1224 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1216 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1225 | 1217 |
1226 // Check that the receiver isn't a smi. | 1218 // Check that the receiver isn't a smi. |
1227 __ JumpIfSmi(rdx, &miss); | 1219 __ JumpIfSmi(rdx, &miss); |
1228 | 1220 |
1229 CheckPrototypes(JSObject::cast(object), rdx, | 1221 CheckPrototypes(JSObject::cast(object), rdx, |
1230 holder, rbx, | 1222 holder, rbx, |
1231 rax, name, &miss, rdi); | 1223 rax, rdi, name, &miss); |
1232 | 1224 |
1233 // Get the elements array of the object. | 1225 // Get the elements array of the object. |
1234 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); | 1226 __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); |
1235 | 1227 |
1236 // Check that the elements are in fast mode (not dictionary). | 1228 // Check that the elements are in fast mode (not dictionary). |
1237 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), Factory::fixed_array_map()); | 1229 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), Factory::fixed_array_map()); |
1238 __ j(not_equal, &miss); | 1230 __ j(not_equal, &miss); |
1239 | 1231 |
1240 // Get the array's length into rcx and calculate new length. | 1232 // Get the array's length into rcx and calculate new length. |
1241 __ SmiToInteger32(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 1233 __ SmiToInteger32(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 | 1320 |
1329 CallInterceptorCompiler compiler(this, arguments(), rcx); | 1321 CallInterceptorCompiler compiler(this, arguments(), rcx); |
1330 compiler.Compile(masm(), | 1322 compiler.Compile(masm(), |
1331 object, | 1323 object, |
1332 holder, | 1324 holder, |
1333 name, | 1325 name, |
1334 &lookup, | 1326 &lookup, |
1335 rdx, | 1327 rdx, |
1336 rbx, | 1328 rbx, |
1337 rdi, | 1329 rdi, |
| 1330 rax, |
1338 &miss); | 1331 &miss); |
1339 | 1332 |
1340 // Restore receiver. | 1333 // Restore receiver. |
1341 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1334 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1342 | 1335 |
1343 // Check that the function really is a function. | 1336 // Check that the function really is a function. |
1344 __ JumpIfSmi(rax, &miss); | 1337 __ JumpIfSmi(rax, &miss); |
1345 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); | 1338 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |
1346 __ j(not_equal, &miss); | 1339 __ j(not_equal, &miss); |
1347 | 1340 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1383 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1391 | 1384 |
1392 // If the object is the holder then we know that it's a global | 1385 // If the object is the holder then we know that it's a global |
1393 // object which can only happen for contextual calls. In this case, | 1386 // object which can only happen for contextual calls. In this case, |
1394 // the receiver cannot be a smi. | 1387 // the receiver cannot be a smi. |
1395 if (object != holder) { | 1388 if (object != holder) { |
1396 __ JumpIfSmi(rdx, &miss); | 1389 __ JumpIfSmi(rdx, &miss); |
1397 } | 1390 } |
1398 | 1391 |
1399 // Check that the maps haven't changed. | 1392 // Check that the maps haven't changed. |
1400 CheckPrototypes(object, rdx, holder, rbx, rax, name, &miss, rdi); | 1393 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, &miss); |
1401 | 1394 |
1402 // Get the value from the cell. | 1395 // Get the value from the cell. |
1403 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); | 1396 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); |
1404 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); | 1397 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); |
1405 | 1398 |
1406 // Check that the cell contains the same function. | 1399 // Check that the cell contains the same function. |
1407 if (Heap::InNewSpace(function)) { | 1400 if (Heap::InNewSpace(function)) { |
1408 // We can't embed a pointer to a function in new space so we have | 1401 // We can't embed a pointer to a function in new space so we have |
1409 // to verify that the shared function info is unchanged. This has | 1402 // to verify that the shared function info is unchanged. This has |
1410 // the nice side effect that multiple closures based on the same | 1403 // the nice side effect that multiple closures based on the same |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 JSObject* holder, | 1448 JSObject* holder, |
1456 AccessorInfo* callback) { | 1449 AccessorInfo* callback) { |
1457 // ----------- S t a t e ------------- | 1450 // ----------- S t a t e ------------- |
1458 // -- rax : receiver | 1451 // -- rax : receiver |
1459 // -- rcx : name | 1452 // -- rcx : name |
1460 // -- rsp[0] : return address | 1453 // -- rsp[0] : return address |
1461 // ----------------------------------- | 1454 // ----------------------------------- |
1462 Label miss; | 1455 Label miss; |
1463 | 1456 |
1464 Failure* failure = Failure::InternalError(); | 1457 Failure* failure = Failure::InternalError(); |
1465 bool success = GenerateLoadCallback(object, holder, rax, rcx, rbx, rdx, | 1458 bool success = GenerateLoadCallback(object, holder, rax, rcx, rbx, rdx, rdi, |
1466 callback, name, &miss, &failure); | 1459 callback, name, &miss, &failure); |
1467 if (!success) return failure; | 1460 if (!success) return failure; |
1468 | 1461 |
1469 __ bind(&miss); | 1462 __ bind(&miss); |
1470 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1463 GenerateLoadMiss(masm(), Code::LOAD_IC); |
1471 | 1464 |
1472 // Return the generated code. | 1465 // Return the generated code. |
1473 return GetCode(CALLBACKS, name); | 1466 return GetCode(CALLBACKS, name); |
1474 } | 1467 } |
1475 | 1468 |
1476 | 1469 |
1477 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, | 1470 Object* LoadStubCompiler::CompileLoadConstant(JSObject* object, |
1478 JSObject* holder, | 1471 JSObject* holder, |
1479 Object* value, | 1472 Object* value, |
1480 String* name) { | 1473 String* name) { |
1481 // ----------- S t a t e ------------- | 1474 // ----------- S t a t e ------------- |
1482 // -- rax : receiver | 1475 // -- rax : receiver |
1483 // -- rcx : name | 1476 // -- rcx : name |
1484 // -- rsp[0] : return address | 1477 // -- rsp[0] : return address |
1485 // ----------------------------------- | 1478 // ----------------------------------- |
1486 Label miss; | 1479 Label miss; |
1487 | 1480 |
1488 GenerateLoadConstant(object, holder, rax, rbx, rdx, value, name, &miss); | 1481 GenerateLoadConstant(object, holder, rax, rbx, rdx, rdi, value, name, &miss); |
1489 __ bind(&miss); | 1482 __ bind(&miss); |
1490 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1483 GenerateLoadMiss(masm(), Code::LOAD_IC); |
1491 | 1484 |
1492 // Return the generated code. | 1485 // Return the generated code. |
1493 return GetCode(CONSTANT_FUNCTION, name); | 1486 return GetCode(CONSTANT_FUNCTION, name); |
1494 } | 1487 } |
1495 | 1488 |
1496 | 1489 |
1497 Object* LoadStubCompiler::CompileLoadNonexistent(String* name, | 1490 Object* LoadStubCompiler::CompileLoadNonexistent(String* name, |
1498 JSObject* object, | 1491 JSObject* object, |
1499 JSObject* last) { | 1492 JSObject* last) { |
1500 // ----------- S t a t e ------------- | 1493 // ----------- S t a t e ------------- |
1501 // -- rax : receiver | 1494 // -- rax : receiver |
1502 // -- rcx : name | 1495 // -- rcx : name |
1503 // -- rsp[0] : return address | 1496 // -- rsp[0] : return address |
1504 // ----------------------------------- | 1497 // ----------------------------------- |
1505 Label miss; | 1498 Label miss; |
1506 | 1499 |
1507 // Chech that receiver is not a smi. | 1500 // Chech that receiver is not a smi. |
1508 __ JumpIfSmi(rax, &miss); | 1501 __ JumpIfSmi(rax, &miss); |
1509 | 1502 |
1510 // Check the maps of the full prototype chain. Also check that | 1503 // Check the maps of the full prototype chain. Also check that |
1511 // global property cells up to (but not including) the last object | 1504 // global property cells up to (but not including) the last object |
1512 // in the prototype chain are empty. | 1505 // in the prototype chain are empty. |
1513 CheckPrototypes(object, rax, last, rbx, rdx, name, &miss, rdi); | 1506 CheckPrototypes(object, rax, last, rbx, rdx, rdi, name, &miss); |
1514 | 1507 |
1515 // If the last object in the prototype chain is a global object, | 1508 // If the last object in the prototype chain is a global object, |
1516 // check that the global property cell is empty. | 1509 // check that the global property cell is empty. |
1517 if (last->IsGlobalObject()) { | 1510 if (last->IsGlobalObject()) { |
1518 Object* cell = GenerateCheckPropertyCell(masm(), | 1511 Object* cell = GenerateCheckPropertyCell(masm(), |
1519 GlobalObject::cast(last), | 1512 GlobalObject::cast(last), |
1520 name, | 1513 name, |
1521 rdx, | 1514 rdx, |
1522 &miss); | 1515 &miss); |
1523 if (cell->IsFailure()) return cell; | 1516 if (cell->IsFailure()) return cell; |
(...skipping 16 matching lines...) Expand all Loading... |
1540 JSObject* holder, | 1533 JSObject* holder, |
1541 int index, | 1534 int index, |
1542 String* name) { | 1535 String* name) { |
1543 // ----------- S t a t e ------------- | 1536 // ----------- S t a t e ------------- |
1544 // -- rax : receiver | 1537 // -- rax : receiver |
1545 // -- rcx : name | 1538 // -- rcx : name |
1546 // -- rsp[0] : return address | 1539 // -- rsp[0] : return address |
1547 // ----------------------------------- | 1540 // ----------------------------------- |
1548 Label miss; | 1541 Label miss; |
1549 | 1542 |
1550 GenerateLoadField(object, holder, rax, rbx, rdx, index, name, &miss); | 1543 GenerateLoadField(object, holder, rax, rbx, rdx, rdi, index, name, &miss); |
1551 __ bind(&miss); | 1544 __ bind(&miss); |
1552 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1545 GenerateLoadMiss(masm(), Code::LOAD_IC); |
1553 | 1546 |
1554 // Return the generated code. | 1547 // Return the generated code. |
1555 return GetCode(FIELD, name); | 1548 return GetCode(FIELD, name); |
1556 } | 1549 } |
1557 | 1550 |
1558 | 1551 |
1559 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, | 1552 Object* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, |
1560 JSObject* holder, | 1553 JSObject* holder, |
(...skipping 10 matching lines...) Expand all Loading... |
1571 | 1564 |
1572 // TODO(368): Compile in the whole chain: all the interceptors in | 1565 // TODO(368): Compile in the whole chain: all the interceptors in |
1573 // prototypes and ultimate answer. | 1566 // prototypes and ultimate answer. |
1574 GenerateLoadInterceptor(receiver, | 1567 GenerateLoadInterceptor(receiver, |
1575 holder, | 1568 holder, |
1576 &lookup, | 1569 &lookup, |
1577 rax, | 1570 rax, |
1578 rcx, | 1571 rcx, |
1579 rdx, | 1572 rdx, |
1580 rbx, | 1573 rbx, |
| 1574 rdi, |
1581 name, | 1575 name, |
1582 &miss); | 1576 &miss); |
1583 | 1577 |
1584 __ bind(&miss); | 1578 __ bind(&miss); |
1585 GenerateLoadMiss(masm(), Code::LOAD_IC); | 1579 GenerateLoadMiss(masm(), Code::LOAD_IC); |
1586 | 1580 |
1587 // Return the generated code. | 1581 // Return the generated code. |
1588 return GetCode(INTERCEPTOR, name); | 1582 return GetCode(INTERCEPTOR, name); |
1589 } | 1583 } |
1590 | 1584 |
(...skipping 11 matching lines...) Expand all Loading... |
1602 Label miss; | 1596 Label miss; |
1603 | 1597 |
1604 // If the object is the holder then we know that it's a global | 1598 // If the object is the holder then we know that it's a global |
1605 // object which can only happen for contextual loads. In this case, | 1599 // object which can only happen for contextual loads. In this case, |
1606 // the receiver cannot be a smi. | 1600 // the receiver cannot be a smi. |
1607 if (object != holder) { | 1601 if (object != holder) { |
1608 __ JumpIfSmi(rax, &miss); | 1602 __ JumpIfSmi(rax, &miss); |
1609 } | 1603 } |
1610 | 1604 |
1611 // Check that the maps haven't changed. | 1605 // Check that the maps haven't changed. |
1612 CheckPrototypes(object, rax, holder, rbx, rdx, name, &miss, rdi); | 1606 CheckPrototypes(object, rax, holder, rbx, rdx, rdi, name, &miss); |
1613 | 1607 |
1614 // Get the value from the cell. | 1608 // Get the value from the cell. |
1615 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); | 1609 __ Move(rbx, Handle<JSGlobalPropertyCell>(cell)); |
1616 __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); | 1610 __ movq(rbx, FieldOperand(rbx, JSGlobalPropertyCell::kValueOffset)); |
1617 | 1611 |
1618 // Check for deleted property if property can actually be deleted. | 1612 // Check for deleted property if property can actually be deleted. |
1619 if (!is_dont_delete) { | 1613 if (!is_dont_delete) { |
1620 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); | 1614 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); |
1621 __ j(equal, &miss); | 1615 __ j(equal, &miss); |
1622 } else if (FLAG_debug_code) { | 1616 } else if (FLAG_debug_code) { |
(...skipping 25 matching lines...) Expand all Loading... |
1648 // ----------------------------------- | 1642 // ----------------------------------- |
1649 Label miss; | 1643 Label miss; |
1650 | 1644 |
1651 __ IncrementCounter(&Counters::keyed_load_callback, 1); | 1645 __ IncrementCounter(&Counters::keyed_load_callback, 1); |
1652 | 1646 |
1653 // Check that the name has not changed. | 1647 // Check that the name has not changed. |
1654 __ Cmp(rax, Handle<String>(name)); | 1648 __ Cmp(rax, Handle<String>(name)); |
1655 __ j(not_equal, &miss); | 1649 __ j(not_equal, &miss); |
1656 | 1650 |
1657 Failure* failure = Failure::InternalError(); | 1651 Failure* failure = Failure::InternalError(); |
1658 bool success = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, | 1652 bool success = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx, rdi, |
1659 callback, name, &miss, &failure); | 1653 callback, name, &miss, &failure); |
1660 if (!success) return failure; | 1654 if (!success) return failure; |
1661 | 1655 |
1662 __ bind(&miss); | 1656 __ bind(&miss); |
1663 __ DecrementCounter(&Counters::keyed_load_callback, 1); | 1657 __ DecrementCounter(&Counters::keyed_load_callback, 1); |
1664 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1658 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1665 | 1659 |
1666 // Return the generated code. | 1660 // Return the generated code. |
1667 return GetCode(CALLBACKS, name); | 1661 return GetCode(CALLBACKS, name); |
1668 } | 1662 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1702 // -- rsp[0] : return address | 1696 // -- rsp[0] : return address |
1703 // ----------------------------------- | 1697 // ----------------------------------- |
1704 Label miss; | 1698 Label miss; |
1705 | 1699 |
1706 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); | 1700 __ IncrementCounter(&Counters::keyed_load_constant_function, 1); |
1707 | 1701 |
1708 // Check that the name has not changed. | 1702 // Check that the name has not changed. |
1709 __ Cmp(rax, Handle<String>(name)); | 1703 __ Cmp(rax, Handle<String>(name)); |
1710 __ j(not_equal, &miss); | 1704 __ j(not_equal, &miss); |
1711 | 1705 |
1712 GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, | 1706 GenerateLoadConstant(receiver, holder, rdx, rbx, rcx, rdi, |
1713 value, name, &miss); | 1707 value, name, &miss); |
1714 __ bind(&miss); | 1708 __ bind(&miss); |
1715 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); | 1709 __ DecrementCounter(&Counters::keyed_load_constant_function, 1); |
1716 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1710 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1717 | 1711 |
1718 // Return the generated code. | 1712 // Return the generated code. |
1719 return GetCode(CONSTANT_FUNCTION, name); | 1713 return GetCode(CONSTANT_FUNCTION, name); |
1720 } | 1714 } |
1721 | 1715 |
1722 | 1716 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 | 1756 |
1763 LookupResult lookup; | 1757 LookupResult lookup; |
1764 LookupPostInterceptor(holder, name, &lookup); | 1758 LookupPostInterceptor(holder, name, &lookup); |
1765 GenerateLoadInterceptor(receiver, | 1759 GenerateLoadInterceptor(receiver, |
1766 holder, | 1760 holder, |
1767 &lookup, | 1761 &lookup, |
1768 rdx, | 1762 rdx, |
1769 rax, | 1763 rax, |
1770 rcx, | 1764 rcx, |
1771 rbx, | 1765 rbx, |
| 1766 rdi, |
1772 name, | 1767 name, |
1773 &miss); | 1768 &miss); |
1774 __ bind(&miss); | 1769 __ bind(&miss); |
1775 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); | 1770 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); |
1776 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1771 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1777 | 1772 |
1778 // Return the generated code. | 1773 // Return the generated code. |
1779 return GetCode(INTERCEPTOR, name); | 1774 return GetCode(INTERCEPTOR, name); |
1780 } | 1775 } |
1781 | 1776 |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1977 // -- rsp[0] : return address | 1972 // -- rsp[0] : return address |
1978 // ----------------------------------- | 1973 // ----------------------------------- |
1979 Label miss; | 1974 Label miss; |
1980 | 1975 |
1981 __ IncrementCounter(&Counters::keyed_load_field, 1); | 1976 __ IncrementCounter(&Counters::keyed_load_field, 1); |
1982 | 1977 |
1983 // Check that the name has not changed. | 1978 // Check that the name has not changed. |
1984 __ Cmp(rax, Handle<String>(name)); | 1979 __ Cmp(rax, Handle<String>(name)); |
1985 __ j(not_equal, &miss); | 1980 __ j(not_equal, &miss); |
1986 | 1981 |
1987 GenerateLoadField(receiver, holder, rdx, rbx, rcx, index, name, &miss); | 1982 GenerateLoadField(receiver, holder, rdx, rbx, rcx, rdi, index, name, &miss); |
1988 | 1983 |
1989 __ bind(&miss); | 1984 __ bind(&miss); |
1990 __ DecrementCounter(&Counters::keyed_load_field, 1); | 1985 __ DecrementCounter(&Counters::keyed_load_field, 1); |
1991 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1986 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1992 | 1987 |
1993 // Return the generated code. | 1988 // Return the generated code. |
1994 return GetCode(FIELD, name); | 1989 return GetCode(FIELD, name); |
1995 } | 1990 } |
1996 | 1991 |
1997 | 1992 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2056 } | 2051 } |
2057 | 2052 |
2058 | 2053 |
2059 void StubCompiler::GenerateLoadInterceptor(JSObject* object, | 2054 void StubCompiler::GenerateLoadInterceptor(JSObject* object, |
2060 JSObject* interceptor_holder, | 2055 JSObject* interceptor_holder, |
2061 LookupResult* lookup, | 2056 LookupResult* lookup, |
2062 Register receiver, | 2057 Register receiver, |
2063 Register name_reg, | 2058 Register name_reg, |
2064 Register scratch1, | 2059 Register scratch1, |
2065 Register scratch2, | 2060 Register scratch2, |
| 2061 Register scratch3, |
2066 String* name, | 2062 String* name, |
2067 Label* miss) { | 2063 Label* miss) { |
2068 ASSERT(interceptor_holder->HasNamedInterceptor()); | 2064 ASSERT(interceptor_holder->HasNamedInterceptor()); |
2069 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 2065 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
2070 | 2066 |
2071 // Check that the receiver isn't a smi. | 2067 // Check that the receiver isn't a smi. |
2072 __ JumpIfSmi(receiver, miss); | 2068 __ JumpIfSmi(receiver, miss); |
2073 | 2069 |
2074 // So far the most popular follow ups for interceptor loads are FIELD | 2070 // So far the most popular follow ups for interceptor loads are FIELD |
2075 // and CALLBACKS, so inline only them, other cases may be added | 2071 // and CALLBACKS, so inline only them, other cases may be added |
2076 // later. | 2072 // later. |
2077 bool compile_followup_inline = false; | 2073 bool compile_followup_inline = false; |
2078 if (lookup->IsProperty() && lookup->IsCacheable()) { | 2074 if (lookup->IsProperty() && lookup->IsCacheable()) { |
2079 if (lookup->type() == FIELD) { | 2075 if (lookup->type() == FIELD) { |
2080 compile_followup_inline = true; | 2076 compile_followup_inline = true; |
2081 } else if (lookup->type() == CALLBACKS && | 2077 } else if (lookup->type() == CALLBACKS && |
2082 lookup->GetCallbackObject()->IsAccessorInfo() && | 2078 lookup->GetCallbackObject()->IsAccessorInfo() && |
2083 AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) { | 2079 AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) { |
2084 compile_followup_inline = true; | 2080 compile_followup_inline = true; |
2085 } | 2081 } |
2086 } | 2082 } |
2087 | 2083 |
2088 if (compile_followup_inline) { | 2084 if (compile_followup_inline) { |
2089 // Compile the interceptor call, followed by inline code to load the | 2085 // Compile the interceptor call, followed by inline code to load the |
2090 // property from further up the prototype chain if the call fails. | 2086 // property from further up the prototype chain if the call fails. |
2091 // Check that the maps haven't changed. | 2087 // Check that the maps haven't changed. |
2092 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 2088 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, |
2093 scratch1, scratch2, name, miss); | 2089 scratch1, scratch2, scratch3, |
| 2090 name, miss); |
2094 ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1)); | 2091 ASSERT(holder_reg.is(receiver) || holder_reg.is(scratch1)); |
2095 | 2092 |
2096 // Save necessary data before invoking an interceptor. | 2093 // Save necessary data before invoking an interceptor. |
2097 // Requires a frame to make GC aware of pushed pointers. | 2094 // Requires a frame to make GC aware of pushed pointers. |
2098 __ EnterInternalFrame(); | 2095 __ EnterInternalFrame(); |
2099 | 2096 |
2100 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { | 2097 if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { |
2101 // CALLBACKS case needs a receiver to be passed into C++ callback. | 2098 // CALLBACKS case needs a receiver to be passed into C++ callback. |
2102 __ push(receiver); | 2099 __ push(receiver); |
2103 } | 2100 } |
(...skipping 27 matching lines...) Expand all Loading... |
2131 __ LeaveInternalFrame(); | 2128 __ LeaveInternalFrame(); |
2132 | 2129 |
2133 // Check that the maps from interceptor's holder to lookup's holder | 2130 // Check that the maps from interceptor's holder to lookup's holder |
2134 // haven't changed. And load lookup's holder into |holder| register. | 2131 // haven't changed. And load lookup's holder into |holder| register. |
2135 if (interceptor_holder != lookup->holder()) { | 2132 if (interceptor_holder != lookup->holder()) { |
2136 holder_reg = CheckPrototypes(interceptor_holder, | 2133 holder_reg = CheckPrototypes(interceptor_holder, |
2137 holder_reg, | 2134 holder_reg, |
2138 lookup->holder(), | 2135 lookup->holder(), |
2139 scratch1, | 2136 scratch1, |
2140 scratch2, | 2137 scratch2, |
| 2138 scratch3, |
2141 name, | 2139 name, |
2142 miss); | 2140 miss); |
2143 } | 2141 } |
2144 | 2142 |
2145 if (lookup->type() == FIELD) { | 2143 if (lookup->type() == FIELD) { |
2146 // We found FIELD property in prototype chain of interceptor's holder. | 2144 // We found FIELD property in prototype chain of interceptor's holder. |
2147 // Retrieve a field from field's holder. | 2145 // Retrieve a field from field's holder. |
2148 GenerateFastPropertyLoad(masm(), rax, holder_reg, | 2146 GenerateFastPropertyLoad(masm(), rax, holder_reg, |
2149 lookup->holder(), lookup->GetFieldIndex()); | 2147 lookup->holder(), lookup->GetFieldIndex()); |
2150 __ ret(0); | 2148 __ ret(0); |
(...skipping 19 matching lines...) Expand all Loading... |
2170 __ push(scratch2); // restore return address | 2168 __ push(scratch2); // restore return address |
2171 | 2169 |
2172 ExternalReference ref = | 2170 ExternalReference ref = |
2173 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 2171 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
2174 __ TailCallExternalReference(ref, 5, 1); | 2172 __ TailCallExternalReference(ref, 5, 1); |
2175 } | 2173 } |
2176 } else { // !compile_followup_inline | 2174 } else { // !compile_followup_inline |
2177 // Call the runtime system to load the interceptor. | 2175 // Call the runtime system to load the interceptor. |
2178 // Check that the maps haven't changed. | 2176 // Check that the maps haven't changed. |
2179 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 2177 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, |
2180 scratch1, scratch2, name, miss); | 2178 scratch1, scratch2, scratch3, |
| 2179 name, miss); |
2181 __ pop(scratch2); // save old return address | 2180 __ pop(scratch2); // save old return address |
2182 PushInterceptorArguments(masm(), receiver, holder_reg, | 2181 PushInterceptorArguments(masm(), receiver, holder_reg, |
2183 name_reg, interceptor_holder); | 2182 name_reg, interceptor_holder); |
2184 __ push(scratch2); // restore old return address | 2183 __ push(scratch2); // restore old return address |
2185 | 2184 |
2186 ExternalReference ref = ExternalReference( | 2185 ExternalReference ref = ExternalReference( |
2187 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); | 2186 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad)); |
2188 __ TailCallExternalReference(ref, 5, 1); | 2187 __ TailCallExternalReference(ref, 5, 1); |
2189 } | 2188 } |
2190 } | 2189 } |
2191 | 2190 |
2192 | 2191 |
2193 bool StubCompiler::GenerateLoadCallback(JSObject* object, | 2192 bool StubCompiler::GenerateLoadCallback(JSObject* object, |
2194 JSObject* holder, | 2193 JSObject* holder, |
2195 Register receiver, | 2194 Register receiver, |
2196 Register name_reg, | 2195 Register name_reg, |
2197 Register scratch1, | 2196 Register scratch1, |
2198 Register scratch2, | 2197 Register scratch2, |
| 2198 Register scratch3, |
2199 AccessorInfo* callback, | 2199 AccessorInfo* callback, |
2200 String* name, | 2200 String* name, |
2201 Label* miss, | 2201 Label* miss, |
2202 Failure** failure) { | 2202 Failure** failure) { |
2203 // Check that the receiver isn't a smi. | 2203 // Check that the receiver isn't a smi. |
2204 __ JumpIfSmi(receiver, miss); | 2204 __ JumpIfSmi(receiver, miss); |
2205 | 2205 |
2206 // Check that the maps haven't changed. | 2206 // Check that the maps haven't changed. |
2207 Register reg = | 2207 Register reg = |
2208 CheckPrototypes(object, receiver, holder, | 2208 CheckPrototypes(object, receiver, holder, |
2209 scratch1, scratch2, name, miss); | 2209 scratch1, scratch2, scratch3, name, miss); |
2210 | 2210 |
2211 // Push the arguments on the JS stack of the caller. | 2211 // Push the arguments on the JS stack of the caller. |
2212 __ pop(scratch2); // remove return address | 2212 __ pop(scratch2); // remove return address |
2213 __ push(receiver); // receiver | 2213 __ push(receiver); // receiver |
2214 __ push(reg); // holder | 2214 __ push(reg); // holder |
2215 __ Move(reg, Handle<AccessorInfo>(callback)); // callback data | 2215 __ Move(reg, Handle<AccessorInfo>(callback)); // callback data |
2216 __ push(reg); | 2216 __ push(reg); |
2217 __ push(FieldOperand(reg, AccessorInfo::kDataOffset)); | 2217 __ push(FieldOperand(reg, AccessorInfo::kDataOffset)); |
2218 __ push(name_reg); // name | 2218 __ push(name_reg); // name |
2219 __ push(scratch2); // restore return address | 2219 __ push(scratch2); // restore return address |
2220 | 2220 |
2221 // Do tail-call to the runtime system. | 2221 // Do tail-call to the runtime system. |
2222 ExternalReference load_callback_property = | 2222 ExternalReference load_callback_property = |
2223 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 2223 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
2224 __ TailCallExternalReference(load_callback_property, 5, 1); | 2224 __ TailCallExternalReference(load_callback_property, 5, 1); |
2225 | 2225 |
2226 return true; | 2226 return true; |
2227 } | 2227 } |
2228 | 2228 |
2229 | 2229 |
2230 Register StubCompiler::CheckPrototypes(JSObject* object, | 2230 Register StubCompiler::CheckPrototypes(JSObject* object, |
2231 Register object_reg, | 2231 Register object_reg, |
2232 JSObject* holder, | 2232 JSObject* holder, |
2233 Register holder_reg, | 2233 Register holder_reg, |
2234 Register scratch, | 2234 Register scratch1, |
| 2235 Register scratch2, |
2235 String* name, | 2236 String* name, |
2236 int save_at_depth, | 2237 int save_at_depth, |
2237 Label* miss, | 2238 Label* miss) { |
2238 Register extra) { | 2239 // Make sure there's no overlap between holder and object registers. |
2239 // Make sure there's no overlap between scratch and the other | 2240 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
2240 // registers. | 2241 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
2241 ASSERT(!scratch.is(object_reg) && !scratch.is(holder_reg)); | 2242 && !scratch2.is(scratch1)); |
2242 | 2243 |
2243 // Keep track of the current object in register reg. On the first | 2244 // Keep track of the current object in register reg. On the first |
2244 // iteration, reg is an alias for object_reg, on later iterations, | 2245 // iteration, reg is an alias for object_reg, on later iterations, |
2245 // it is an alias for holder_reg. | 2246 // it is an alias for holder_reg. |
2246 Register reg = object_reg; | 2247 Register reg = object_reg; |
2247 int depth = 0; | 2248 int depth = 0; |
2248 | 2249 |
2249 if (save_at_depth == depth) { | 2250 if (save_at_depth == depth) { |
2250 __ movq(Operand(rsp, kPointerSize), object_reg); | 2251 __ movq(Operand(rsp, kPointerSize), object_reg); |
2251 } | 2252 } |
(...skipping 21 matching lines...) Expand all Loading... |
2273 name = String::cast(lookup_result); | 2274 name = String::cast(lookup_result); |
2274 } | 2275 } |
2275 } | 2276 } |
2276 ASSERT(current->property_dictionary()->FindEntry(name) == | 2277 ASSERT(current->property_dictionary()->FindEntry(name) == |
2277 StringDictionary::kNotFound); | 2278 StringDictionary::kNotFound); |
2278 | 2279 |
2279 GenerateDictionaryNegativeLookup(masm(), | 2280 GenerateDictionaryNegativeLookup(masm(), |
2280 miss, | 2281 miss, |
2281 reg, | 2282 reg, |
2282 name, | 2283 name, |
2283 scratch, | 2284 scratch1, |
2284 extra); | 2285 scratch2); |
2285 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 2286 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
2286 reg = holder_reg; // from now the object is in holder_reg | 2287 reg = holder_reg; // from now the object is in holder_reg |
2287 __ movq(reg, FieldOperand(scratch, Map::kPrototypeOffset)); | 2288 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
2288 } else if (Heap::InNewSpace(prototype)) { | 2289 } else if (Heap::InNewSpace(prototype)) { |
2289 // Get the map of the current object. | 2290 // Get the map of the current object. |
2290 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 2291 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
2291 __ Cmp(scratch, Handle<Map>(current->map())); | 2292 __ Cmp(scratch1, Handle<Map>(current->map())); |
2292 // Branch on the result of the map check. | 2293 // Branch on the result of the map check. |
2293 __ j(not_equal, miss); | 2294 __ j(not_equal, miss); |
2294 // Check access rights to the global object. This has to happen | 2295 // Check access rights to the global object. This has to happen |
2295 // after the map check so that we know that the object is | 2296 // after the map check so that we know that the object is |
2296 // actually a global object. | 2297 // actually a global object. |
2297 if (current->IsJSGlobalProxy()) { | 2298 if (current->IsJSGlobalProxy()) { |
2298 __ CheckAccessGlobalProxy(reg, scratch, miss); | 2299 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
2299 | 2300 |
2300 // Restore scratch register to be the map of the object. | 2301 // Restore scratch register to be the map of the object. |
2301 // We load the prototype from the map in the scratch register. | 2302 // We load the prototype from the map in the scratch register. |
2302 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); | 2303 __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); |
2303 } | 2304 } |
2304 // The prototype is in new space; we cannot store a reference | 2305 // The prototype is in new space; we cannot store a reference |
2305 // to it in the code. Load it from the map. | 2306 // to it in the code. Load it from the map. |
2306 reg = holder_reg; // from now the object is in holder_reg | 2307 reg = holder_reg; // from now the object is in holder_reg |
2307 __ movq(reg, FieldOperand(scratch, Map::kPrototypeOffset)); | 2308 __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); |
2308 | 2309 |
2309 } else { | 2310 } else { |
2310 // Check the map of the current object. | 2311 // Check the map of the current object. |
2311 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), | 2312 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
2312 Handle<Map>(current->map())); | 2313 Handle<Map>(current->map())); |
2313 // Branch on the result of the map check. | 2314 // Branch on the result of the map check. |
2314 __ j(not_equal, miss); | 2315 __ j(not_equal, miss); |
2315 // Check access rights to the global object. This has to happen | 2316 // Check access rights to the global object. This has to happen |
2316 // after the map check so that we know that the object is | 2317 // after the map check so that we know that the object is |
2317 // actually a global object. | 2318 // actually a global object. |
2318 if (current->IsJSGlobalProxy()) { | 2319 if (current->IsJSGlobalProxy()) { |
2319 __ CheckAccessGlobalProxy(reg, scratch, miss); | 2320 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
2320 } | 2321 } |
2321 // The prototype is in old space; load it directly. | 2322 // The prototype is in old space; load it directly. |
2322 reg = holder_reg; // from now the object is in holder_reg | 2323 reg = holder_reg; // from now the object is in holder_reg |
2323 __ Move(reg, Handle<JSObject>(prototype)); | 2324 __ Move(reg, Handle<JSObject>(prototype)); |
2324 } | 2325 } |
2325 | 2326 |
2326 if (save_at_depth == depth) { | 2327 if (save_at_depth == depth) { |
2327 __ movq(Operand(rsp, kPointerSize), reg); | 2328 __ movq(Operand(rsp, kPointerSize), reg); |
2328 } | 2329 } |
2329 | 2330 |
2330 // Go to the next object in the prototype chain. | 2331 // Go to the next object in the prototype chain. |
2331 current = prototype; | 2332 current = prototype; |
2332 } | 2333 } |
2333 | 2334 |
2334 // Check the holder map. | 2335 // Check the holder map. |
2335 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map())); | 2336 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), Handle<Map>(holder->map())); |
2336 __ j(not_equal, miss); | 2337 __ j(not_equal, miss); |
2337 | 2338 |
2338 // Log the check depth. | 2339 // Log the check depth. |
2339 LOG(IntEvent("check-maps-depth", depth + 1)); | 2340 LOG(IntEvent("check-maps-depth", depth + 1)); |
2340 | 2341 |
2341 // Perform security check for access to the global object and return | 2342 // Perform security check for access to the global object and return |
2342 // the holder register. | 2343 // the holder register. |
2343 ASSERT(current == holder); | 2344 ASSERT(current == holder); |
2344 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 2345 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
2345 if (current->IsJSGlobalProxy()) { | 2346 if (current->IsJSGlobalProxy()) { |
2346 __ CheckAccessGlobalProxy(reg, scratch, miss); | 2347 __ CheckAccessGlobalProxy(reg, scratch1, miss); |
2347 } | 2348 } |
2348 | 2349 |
2349 // If we've skipped any global objects, it's not enough to verify | 2350 // If we've skipped any global objects, it's not enough to verify |
2350 // that their maps haven't changed. We also need to check that the | 2351 // that their maps haven't changed. We also need to check that the |
2351 // property cell for the property is still empty. | 2352 // property cell for the property is still empty. |
2352 current = object; | 2353 current = object; |
2353 while (current != holder) { | 2354 while (current != holder) { |
2354 if (current->IsGlobalObject()) { | 2355 if (current->IsGlobalObject()) { |
2355 Object* cell = GenerateCheckPropertyCell(masm(), | 2356 Object* cell = GenerateCheckPropertyCell(masm(), |
2356 GlobalObject::cast(current), | 2357 GlobalObject::cast(current), |
2357 name, | 2358 name, |
2358 scratch, | 2359 scratch1, |
2359 miss); | 2360 miss); |
2360 if (cell->IsFailure()) { | 2361 if (cell->IsFailure()) { |
2361 set_failure(Failure::cast(cell)); | 2362 set_failure(Failure::cast(cell)); |
2362 return reg; | 2363 return reg; |
2363 } | 2364 } |
2364 } | 2365 } |
2365 current = JSObject::cast(current->GetPrototype()); | 2366 current = JSObject::cast(current->GetPrototype()); |
2366 } | 2367 } |
2367 | 2368 |
2368 // Return the register containing the holder. | 2369 // Return the register containing the holder. |
2369 return reg; | 2370 return reg; |
2370 } | 2371 } |
2371 | 2372 |
2372 | 2373 |
2373 void StubCompiler::GenerateLoadField(JSObject* object, | 2374 void StubCompiler::GenerateLoadField(JSObject* object, |
2374 JSObject* holder, | 2375 JSObject* holder, |
2375 Register receiver, | 2376 Register receiver, |
2376 Register scratch1, | 2377 Register scratch1, |
2377 Register scratch2, | 2378 Register scratch2, |
| 2379 Register scratch3, |
2378 int index, | 2380 int index, |
2379 String* name, | 2381 String* name, |
2380 Label* miss) { | 2382 Label* miss) { |
2381 // Check that the receiver isn't a smi. | 2383 // Check that the receiver isn't a smi. |
2382 __ JumpIfSmi(receiver, miss); | 2384 __ JumpIfSmi(receiver, miss); |
2383 | 2385 |
2384 // Check the prototype chain. | 2386 // Check the prototype chain. |
2385 Register reg = | 2387 Register reg = |
2386 CheckPrototypes(object, receiver, holder, | 2388 CheckPrototypes(object, receiver, holder, |
2387 scratch1, scratch2, name, miss); | 2389 scratch1, scratch2, scratch3, name, miss); |
2388 | 2390 |
2389 // Get the value from the properties. | 2391 // Get the value from the properties. |
2390 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); | 2392 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); |
2391 __ ret(0); | 2393 __ ret(0); |
2392 } | 2394 } |
2393 | 2395 |
2394 | 2396 |
2395 void StubCompiler::GenerateLoadConstant(JSObject* object, | 2397 void StubCompiler::GenerateLoadConstant(JSObject* object, |
2396 JSObject* holder, | 2398 JSObject* holder, |
2397 Register receiver, | 2399 Register receiver, |
2398 Register scratch1, | 2400 Register scratch1, |
2399 Register scratch2, | 2401 Register scratch2, |
| 2402 Register scratch3, |
2400 Object* value, | 2403 Object* value, |
2401 String* name, | 2404 String* name, |
2402 Label* miss) { | 2405 Label* miss) { |
2403 // Check that the receiver isn't a smi. | 2406 // Check that the receiver isn't a smi. |
2404 __ JumpIfSmi(receiver, miss); | 2407 __ JumpIfSmi(receiver, miss); |
2405 | 2408 |
2406 // Check that the maps haven't changed. | 2409 // Check that the maps haven't changed. |
2407 Register reg = | 2410 Register reg = |
2408 CheckPrototypes(object, receiver, holder, | 2411 CheckPrototypes(object, receiver, holder, |
2409 scratch1, scratch2, name, miss); | 2412 scratch1, scratch2, scratch3, name, miss); |
2410 | 2413 |
2411 // Return the constant value. | 2414 // Return the constant value. |
2412 __ Move(rax, Handle<Object>(value)); | 2415 __ Move(rax, Handle<Object>(value)); |
2413 __ ret(0); | 2416 __ ret(0); |
2414 } | 2417 } |
2415 | 2418 |
2416 | 2419 |
2417 // Specialized stub for constructing objects from functions which only have only | 2420 // Specialized stub for constructing objects from functions which only have only |
2418 // simple assignments of the form this.x = ...; in their body. | 2421 // simple assignments of the form this.x = ...; in their body. |
2419 Object* ConstructStubCompiler::CompileConstructStub( | 2422 Object* ConstructStubCompiler::CompileConstructStub( |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2542 // Return the generated code. | 2545 // Return the generated code. |
2543 return GetCode(); | 2546 return GetCode(); |
2544 } | 2547 } |
2545 | 2548 |
2546 | 2549 |
2547 #undef __ | 2550 #undef __ |
2548 | 2551 |
2549 } } // namespace v8::internal | 2552 } } // namespace v8::internal |
2550 | 2553 |
2551 #endif // V8_TARGET_ARCH_X64 | 2554 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |