Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 99923008: Merged r17459, r17462, r17474 into 3.20 branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/3.20
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/version.cc ('k') | test/mjsunit/regress/regress-2980.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 #endif 99 #endif
100 100
101 // Jump to the first instruction in the code stub. 101 // Jump to the first instruction in the code stub.
102 __ addq(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag)); 102 __ addq(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag));
103 __ jmp(kScratchRegister); 103 __ jmp(kScratchRegister);
104 104
105 __ bind(&miss); 105 __ bind(&miss);
106 } 106 }
107 107
108 108
109 // Helper function used to check that the dictionary doesn't contain 109 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm,
110 // the property. This function may return false negatives, so miss_label 110 Label* miss_label,
111 // must always call a backup property check that is complete. 111 Register receiver,
112 // This function is safe to call if the receiver has fast properties. 112 Handle<Name> name,
113 // Name must be unique and receiver must be a heap object. 113 Register scratch0,
114 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, 114 Register scratch1) {
115 Label* miss_label,
116 Register receiver,
117 Handle<Name> name,
118 Register r0,
119 Register r1) {
120 ASSERT(name->IsUniqueName()); 115 ASSERT(name->IsUniqueName());
116 ASSERT(!receiver.is(scratch0));
121 Counters* counters = masm->isolate()->counters(); 117 Counters* counters = masm->isolate()->counters();
122 __ IncrementCounter(counters->negative_lookups(), 1); 118 __ IncrementCounter(counters->negative_lookups(), 1);
123 __ IncrementCounter(counters->negative_lookups_miss(), 1); 119 __ IncrementCounter(counters->negative_lookups_miss(), 1);
124 120
125 __ movq(r0, FieldOperand(receiver, HeapObject::kMapOffset)); 121 __ movq(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
126 122
127 const int kInterceptorOrAccessCheckNeededMask = 123 const int kInterceptorOrAccessCheckNeededMask =
128 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 124 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
129 125
130 // Bail out if the receiver has a named interceptor or requires access checks. 126 // Bail out if the receiver has a named interceptor or requires access checks.
131 __ testb(FieldOperand(r0, Map::kBitFieldOffset), 127 __ testb(FieldOperand(scratch0, Map::kBitFieldOffset),
132 Immediate(kInterceptorOrAccessCheckNeededMask)); 128 Immediate(kInterceptorOrAccessCheckNeededMask));
133 __ j(not_zero, miss_label); 129 __ j(not_zero, miss_label);
134 130
135 // Check that receiver is a JSObject. 131 // Check that receiver is a JSObject.
136 __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE); 132 __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE);
137 __ j(below, miss_label); 133 __ j(below, miss_label);
138 134
139 // Load properties array. 135 // Load properties array.
140 Register properties = r0; 136 Register properties = scratch0;
141 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 137 __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
142 138
143 // Check that the properties array is a dictionary. 139 // Check that the properties array is a dictionary.
144 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), 140 __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset),
145 Heap::kHashTableMapRootIndex); 141 Heap::kHashTableMapRootIndex);
146 __ j(not_equal, miss_label); 142 __ j(not_equal, miss_label);
147 143
148 Label done; 144 Label done;
149 NameDictionaryLookupStub::GenerateNegativeLookup(masm, 145 NameDictionaryLookupStub::GenerateNegativeLookup(masm,
150 miss_label, 146 miss_label,
151 &done, 147 &done,
152 properties, 148 properties,
153 name, 149 name,
154 r1); 150 scratch1);
155 __ bind(&done); 151 __ bind(&done);
156 __ DecrementCounter(counters->negative_lookups_miss(), 1); 152 __ DecrementCounter(counters->negative_lookups_miss(), 1);
157 } 153 }
158 154
159 155
160 void StubCache::GenerateProbe(MacroAssembler* masm, 156 void StubCache::GenerateProbe(MacroAssembler* masm,
161 Code::Flags flags, 157 Code::Flags flags,
162 Register receiver, 158 Register receiver,
163 Register name, 159 Register name,
164 Register scratch, 160 Register scratch,
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 729 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
734 Label* label, 730 Label* label,
735 Handle<Name> name) { 731 Handle<Name> name) {
736 if (!label->is_unused()) { 732 if (!label->is_unused()) {
737 __ bind(label); 733 __ bind(label);
738 __ Move(this->name(), name); 734 __ Move(this->name(), name);
739 } 735 }
740 } 736 }
741 737
742 738
743 // Generate code to check that a global property cell is empty. Create 739 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
744 // the property cell at compilation time if no cell exists for the 740 Handle<JSGlobalObject> global,
745 // property. 741 Handle<Name> name,
746 static void GenerateCheckPropertyCell(MacroAssembler* masm, 742 Register scratch,
747 Handle<GlobalObject> global, 743 Label* miss) {
748 Handle<Name> name,
749 Register scratch,
750 Label* miss) {
751 Handle<PropertyCell> cell = 744 Handle<PropertyCell> cell =
752 GlobalObject::EnsurePropertyCell(global, name); 745 JSGlobalObject::EnsurePropertyCell(global, name);
753 ASSERT(cell->value()->IsTheHole()); 746 ASSERT(cell->value()->IsTheHole());
754 __ Move(scratch, cell); 747 __ Move(scratch, cell);
755 __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 748 __ Cmp(FieldOperand(scratch, Cell::kValueOffset),
756 masm->isolate()->factory()->the_hole_value()); 749 masm->isolate()->factory()->the_hole_value());
757 __ j(not_equal, miss); 750 __ j(not_equal, miss);
758 } 751 }
759 752
760 753
761 void BaseStoreStubCompiler::GenerateNegativeHolderLookup( 754 void BaseStoreStubCompiler::GenerateNegativeHolderLookup(
762 MacroAssembler* masm, 755 MacroAssembler* masm,
763 Handle<JSObject> holder, 756 Handle<JSObject> holder,
764 Register holder_reg, 757 Register holder_reg,
765 Handle<Name> name, 758 Handle<Name> name,
766 Label* miss) { 759 Label* miss) {
767 if (holder->IsJSGlobalObject()) { 760 if (holder->IsJSGlobalObject()) {
768 GenerateCheckPropertyCell( 761 GenerateCheckPropertyCell(
769 masm, Handle<GlobalObject>::cast(holder), name, scratch1(), miss); 762 masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss);
770 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 763 } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
771 GenerateDictionaryNegativeLookup( 764 GenerateDictionaryNegativeLookup(
772 masm, miss, holder_reg, name, scratch1(), scratch2()); 765 masm, miss, holder_reg, name, scratch1(), scratch2());
773 } 766 }
774 } 767 }
775 768
776 769
777 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 770 // Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
778 // store is successful. 771 // store is successful.
779 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 772 void BaseStoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm,
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 EMIT_REMEMBERED_SET, smi_check); 1003 EMIT_REMEMBERED_SET, smi_check);
1011 } 1004 }
1012 } 1005 }
1013 1006
1014 // Return the value (register rax). 1007 // Return the value (register rax).
1015 ASSERT(value_reg.is(rax)); 1008 ASSERT(value_reg.is(rax));
1016 __ ret(0); 1009 __ ret(0);
1017 } 1010 }
1018 1011
1019 1012
1020 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 1013 void StubCompiler::GenerateCheckPropertyCells(MacroAssembler* masm,
1021 // from object to (but not including) holder. 1014 Handle<JSObject> object,
1022 static void GenerateCheckPropertyCells(MacroAssembler* masm, 1015 Handle<JSObject> holder,
1023 Handle<JSObject> object, 1016 Handle<Name> name,
1024 Handle<JSObject> holder, 1017 Register scratch,
1025 Handle<Name> name, 1018 Label* miss) {
1026 Register scratch,
1027 Label* miss) {
1028 Handle<JSObject> current = object; 1019 Handle<JSObject> current = object;
1029 while (!current.is_identical_to(holder)) { 1020 while (!current.is_identical_to(holder)) {
1030 if (current->IsGlobalObject()) { 1021 if (current->IsJSGlobalObject()) {
1031 GenerateCheckPropertyCell(masm, 1022 GenerateCheckPropertyCell(masm,
1032 Handle<GlobalObject>::cast(current), 1023 Handle<JSGlobalObject>::cast(current),
1033 name, 1024 name,
1034 scratch, 1025 scratch,
1035 miss); 1026 miss);
1036 } 1027 }
1037 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 1028 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
1038 } 1029 }
1039 } 1030 }
1040 1031
1041 1032
1042 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 1033 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); 1224 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT);
1234 __ cmpq(scratch2(), scratch3()); 1225 __ cmpq(scratch2(), scratch3());
1235 __ j(not_equal, &miss); 1226 __ j(not_equal, &miss);
1236 } 1227 }
1237 1228
1238 HandlerFrontendFooter(name, success, &miss); 1229 HandlerFrontendFooter(name, success, &miss);
1239 return reg; 1230 return reg;
1240 } 1231 }
1241 1232
1242 1233
1243 void BaseLoadStubCompiler::NonexistentHandlerFrontend(
1244 Handle<JSObject> object,
1245 Handle<JSObject> last,
1246 Handle<Name> name,
1247 Label* success,
1248 Handle<GlobalObject> global) {
1249 Label miss;
1250
1251 HandlerFrontendHeader(object, receiver(), last, name, &miss);
1252
1253 // If the last object in the prototype chain is a global object,
1254 // check that the global property cell is empty.
1255 if (!global.is_null()) {
1256 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
1257 }
1258
1259 HandlerFrontendFooter(name, success, &miss);
1260 }
1261
1262
1263 void BaseLoadStubCompiler::GenerateLoadField(Register reg, 1234 void BaseLoadStubCompiler::GenerateLoadField(Register reg,
1264 Handle<JSObject> holder, 1235 Handle<JSObject> holder,
1265 PropertyIndex field, 1236 PropertyIndex field,
1266 Representation representation) { 1237 Representation representation) {
1267 if (!reg.is(receiver())) __ movq(receiver(), reg); 1238 if (!reg.is(receiver())) __ movq(receiver(), reg);
1268 if (kind() == Code::LOAD_IC) { 1239 if (kind() == Code::LOAD_IC) {
1269 LoadFieldStub stub(field.is_inobject(holder), 1240 LoadFieldStub stub(field.is_inobject(holder),
1270 field.translate(holder), 1241 field.translate(holder),
1271 representation); 1242 representation);
1272 GenerateTailCall(masm(), stub.GetCode(isolate())); 1243 GenerateTailCall(masm(), stub.GetCode(isolate()));
(...skipping 1534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2807 // Return the generated code. 2778 // Return the generated code.
2808 return GetICCode( 2779 return GetICCode(
2809 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 2780 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
2810 } 2781 }
2811 2782
2812 2783
2813 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2784 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
2814 Handle<JSObject> object, 2785 Handle<JSObject> object,
2815 Handle<JSObject> last, 2786 Handle<JSObject> last,
2816 Handle<Name> name, 2787 Handle<Name> name,
2817 Handle<GlobalObject> global) { 2788 Handle<JSGlobalObject> global) {
2818 Label success; 2789 Label success;
2819 2790
2820 NonexistentHandlerFrontend(object, last, name, &success, global); 2791 NonexistentHandlerFrontend(object, last, name, &success, global);
2821 2792
2822 __ bind(&success); 2793 __ bind(&success);
2823 // Return undefined if maps of the full prototype chain are still the 2794 // Return undefined if maps of the full prototype chain are still the
2824 // same and no global property with this name contains a value. 2795 // same and no global property with this name contains a value.
2825 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2796 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2826 __ ret(0); 2797 __ ret(0);
2827 2798
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after
3513 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3484 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3514 } 3485 }
3515 } 3486 }
3516 3487
3517 3488
3518 #undef __ 3489 #undef __
3519 3490
3520 } } // namespace v8::internal 3491 } } // namespace v8::internal
3521 3492
3522 #endif // V8_TARGET_ARCH_X64 3493 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/version.cc ('k') | test/mjsunit/regress/regress-2980.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698