OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 ASSERT(sizeof(Entry) == 16); | 156 ASSERT(sizeof(Entry) == 16); |
157 | 157 |
158 // Make sure the flags do not name a specific type. | 158 // Make sure the flags do not name a specific type. |
159 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); | 159 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); |
160 | 160 |
161 // Make sure that there are no register conflicts. | 161 // Make sure that there are no register conflicts. |
162 ASSERT(!scratch.is(receiver)); | 162 ASSERT(!scratch.is(receiver)); |
163 ASSERT(!scratch.is(name)); | 163 ASSERT(!scratch.is(name)); |
164 | 164 |
165 // Check that the receiver isn't a smi. | 165 // Check that the receiver isn't a smi. |
166 __ testl(receiver, Immediate(kSmiTagMask)); | 166 __ JumpIfSmi(receiver, &miss); |
167 __ j(zero, &miss); | |
168 | 167 |
169 // Get the map of the receiver and compute the hash. | 168 // Get the map of the receiver and compute the hash. |
170 __ movl(scratch, FieldOperand(name, String::kLengthOffset)); | 169 __ movl(scratch, FieldOperand(name, String::kLengthOffset)); |
171 // Use only the low 32 bits of the map pointer. | 170 // Use only the low 32 bits of the map pointer. |
172 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 171 __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
173 __ xor_(scratch, Immediate(flags)); | 172 __ xor_(scratch, Immediate(flags)); |
174 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); | 173 __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); |
175 | 174 |
176 // Probe the primary table. | 175 // Probe the primary table. |
177 ProbeTable(masm, flags, kPrimary, name, scratch); | 176 ProbeTable(masm, flags, kPrimary, name, scratch); |
(...skipping 19 matching lines...) Expand all Loading... |
197 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 196 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
198 Builtins::Name storage_extend, | 197 Builtins::Name storage_extend, |
199 JSObject* object, | 198 JSObject* object, |
200 int index, | 199 int index, |
201 Map* transition, | 200 Map* transition, |
202 Register receiver_reg, | 201 Register receiver_reg, |
203 Register name_reg, | 202 Register name_reg, |
204 Register scratch, | 203 Register scratch, |
205 Label* miss_label) { | 204 Label* miss_label) { |
206 // Check that the object isn't a smi. | 205 // Check that the object isn't a smi. |
207 __ testl(receiver_reg, Immediate(kSmiTagMask)); | 206 __ JumpIfSmi(receiver_reg, miss_label); |
208 __ j(zero, miss_label); | |
209 | 207 |
210 // Check that the map of the object hasn't changed. | 208 // Check that the map of the object hasn't changed. |
211 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 209 __ Cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
212 Handle<Map>(object->map())); | 210 Handle<Map>(object->map())); |
213 __ j(not_equal, miss_label); | 211 __ j(not_equal, miss_label); |
214 | 212 |
215 // Perform global security token check if needed. | 213 // Perform global security token check if needed. |
216 if (object->IsJSGlobalProxy()) { | 214 if (object->IsJSGlobalProxy()) { |
217 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 215 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
218 } | 216 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 // Return the value (register rax). | 266 // Return the value (register rax). |
269 __ ret(0); | 267 __ ret(0); |
270 } | 268 } |
271 | 269 |
272 | 270 |
273 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, | 271 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, |
274 Register receiver, | 272 Register receiver, |
275 Register scratch, | 273 Register scratch, |
276 Label* miss_label) { | 274 Label* miss_label) { |
277 // Check that the receiver isn't a smi. | 275 // Check that the receiver isn't a smi. |
278 __ testl(receiver, Immediate(kSmiTagMask)); | 276 __ JumpIfSmi(receiver, miss_label); |
279 __ j(zero, miss_label); | |
280 | 277 |
281 // Check that the object is a JS array. | 278 // Check that the object is a JS array. |
282 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); | 279 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); |
283 __ j(not_equal, miss_label); | 280 __ j(not_equal, miss_label); |
284 | 281 |
285 // Load length directly from the JS array. | 282 // Load length directly from the JS array. |
286 __ movq(rax, FieldOperand(receiver, JSArray::kLengthOffset)); | 283 __ movq(rax, FieldOperand(receiver, JSArray::kLengthOffset)); |
287 __ ret(0); | 284 __ ret(0); |
288 } | 285 } |
289 | 286 |
290 | 287 |
291 // Generate code to check if an object is a string. If the object is | 288 // Generate code to check if an object is a string. If the object is |
292 // a string, the map's instance type is left in the scratch register. | 289 // a string, the map's instance type is left in the scratch register. |
293 static void GenerateStringCheck(MacroAssembler* masm, | 290 static void GenerateStringCheck(MacroAssembler* masm, |
294 Register receiver, | 291 Register receiver, |
295 Register scratch, | 292 Register scratch, |
296 Label* smi, | 293 Label* smi, |
297 Label* non_string_object) { | 294 Label* non_string_object) { |
298 // Check that the object isn't a smi. | 295 // Check that the object isn't a smi. |
299 __ testl(receiver, Immediate(kSmiTagMask)); | 296 __ JumpIfSmi(receiver, smi); |
300 __ j(zero, smi); | |
301 | 297 |
302 // Check that the object is a string. | 298 // Check that the object is a string. |
303 __ movq(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 299 __ movq(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
304 __ movzxbq(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 300 __ movzxbq(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
305 ASSERT(kNotStringTag != 0); | 301 ASSERT(kNotStringTag != 0); |
306 __ testl(scratch, Immediate(kNotStringTag)); | 302 __ testl(scratch, Immediate(kNotStringTag)); |
307 __ j(not_zero, non_string_object); | 303 __ j(not_zero, non_string_object); |
308 } | 304 } |
309 | 305 |
310 | 306 |
311 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, | 307 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, |
312 Register receiver, | 308 Register receiver, |
313 Register scratch, | 309 Register scratch, |
314 Label* miss) { | 310 Label* miss) { |
315 Label load_length, check_wrapper; | 311 Label load_length, check_wrapper; |
316 | 312 |
317 // Check if the object is a string leaving the instance type in the | 313 // Check if the object is a string leaving the instance type in the |
318 // scratch register. | 314 // scratch register. |
319 GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper); | 315 GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper); |
320 | 316 |
321 // Load length directly from the string. | 317 // Load length directly from the string. |
322 __ bind(&load_length); | 318 __ bind(&load_length); |
323 __ and_(scratch, Immediate(kStringSizeMask)); | 319 __ and_(scratch, Immediate(kStringSizeMask)); |
324 __ movl(rax, FieldOperand(receiver, String::kLengthOffset)); | 320 __ movl(rax, FieldOperand(receiver, String::kLengthOffset)); |
325 // rcx is also the receiver. | 321 // rcx is also the receiver. |
326 __ lea(rcx, Operand(scratch, String::kLongLengthShift)); | 322 __ lea(rcx, Operand(scratch, String::kLongLengthShift)); |
327 __ shr(rax); // rcx is implicit shift register. | 323 __ shr(rax); // rcx is implicit shift register. |
328 __ shl(rax, Immediate(kSmiTagSize)); | 324 __ Integer32ToSmi(rax, rax); |
329 __ ret(0); | 325 __ ret(0); |
330 | 326 |
331 // Check if the object is a JSValue wrapper. | 327 // Check if the object is a JSValue wrapper. |
332 __ bind(&check_wrapper); | 328 __ bind(&check_wrapper); |
333 __ cmpl(scratch, Immediate(JS_VALUE_TYPE)); | 329 __ cmpl(scratch, Immediate(JS_VALUE_TYPE)); |
334 __ j(not_equal, miss); | 330 __ j(not_equal, miss); |
335 | 331 |
336 // Check if the wrapped value is a string and load the length | 332 // Check if the wrapped value is a string and load the length |
337 // directly if it is. | 333 // directly if it is. |
338 __ movq(receiver, FieldOperand(receiver, JSValue::kValueOffset)); | 334 __ movq(receiver, FieldOperand(receiver, JSValue::kValueOffset)); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 String* name, | 524 String* name, |
529 LookupResult* lookup, | 525 LookupResult* lookup, |
530 Register receiver, | 526 Register receiver, |
531 Register scratch1, | 527 Register scratch1, |
532 Register scratch2, | 528 Register scratch2, |
533 Label* miss) { | 529 Label* miss) { |
534 ASSERT(holder->HasNamedInterceptor()); | 530 ASSERT(holder->HasNamedInterceptor()); |
535 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 531 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
536 | 532 |
537 // Check that the receiver isn't a smi. | 533 // Check that the receiver isn't a smi. |
538 __ testl(receiver, Immediate(kSmiTagMask)); | 534 __ JumpIfSmi(receiver, miss); |
539 __ j(zero, miss); | |
540 | 535 |
541 // Check that the maps haven't changed. | 536 // Check that the maps haven't changed. |
542 Register reg = | 537 Register reg = |
543 stub_compiler->CheckPrototypes(object, receiver, holder, | 538 stub_compiler->CheckPrototypes(object, receiver, holder, |
544 scratch1, scratch2, name, miss); | 539 scratch1, scratch2, name, miss); |
545 | 540 |
546 if (lookup->IsValid() && lookup->IsCacheable()) { | 541 if (lookup->IsValid() && lookup->IsCacheable()) { |
547 compiler->CompileCacheable(masm, | 542 compiler->CompileCacheable(masm, |
548 stub_compiler, | 543 stub_compiler, |
549 receiver, | 544 receiver, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 // rsp[(argc + 2) * 8] function name | 689 // rsp[(argc + 2) * 8] function name |
695 | 690 |
696 Label miss; | 691 Label miss; |
697 | 692 |
698 // Get the receiver from the stack. | 693 // Get the receiver from the stack. |
699 const int argc = arguments().immediate(); | 694 const int argc = arguments().immediate(); |
700 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 695 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
701 | 696 |
702 // Check that the receiver isn't a smi. | 697 // Check that the receiver isn't a smi. |
703 if (check != NUMBER_CHECK) { | 698 if (check != NUMBER_CHECK) { |
704 __ testl(rdx, Immediate(kSmiTagMask)); | 699 __ JumpIfSmi(rdx, &miss); |
705 __ j(zero, &miss); | |
706 } | 700 } |
707 | 701 |
708 // Make sure that it's okay not to patch the on stack receiver | 702 // Make sure that it's okay not to patch the on stack receiver |
709 // unless we're doing a receiver map check. | 703 // unless we're doing a receiver map check. |
710 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 704 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
711 | 705 |
712 switch (check) { | 706 switch (check) { |
713 case RECEIVER_MAP_CHECK: | 707 case RECEIVER_MAP_CHECK: |
714 // Check that the maps haven't changed. | 708 // Check that the maps haven't changed. |
715 CheckPrototypes(JSObject::cast(object), rdx, holder, | 709 CheckPrototypes(JSObject::cast(object), rdx, holder, |
(...skipping 15 matching lines...) Expand all Loading... |
731 GenerateLoadGlobalFunctionPrototype(masm(), | 725 GenerateLoadGlobalFunctionPrototype(masm(), |
732 Context::STRING_FUNCTION_INDEX, | 726 Context::STRING_FUNCTION_INDEX, |
733 rcx); | 727 rcx); |
734 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, | 728 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, |
735 rbx, rdx, name, &miss); | 729 rbx, rdx, name, &miss); |
736 break; | 730 break; |
737 | 731 |
738 case NUMBER_CHECK: { | 732 case NUMBER_CHECK: { |
739 Label fast; | 733 Label fast; |
740 // Check that the object is a smi or a heap number. | 734 // Check that the object is a smi or a heap number. |
741 __ testl(rdx, Immediate(kSmiTagMask)); | 735 __ JumpIfSmi(rdx, &fast); |
742 __ j(zero, &fast); | |
743 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx); | 736 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rcx); |
744 __ j(not_equal, &miss); | 737 __ j(not_equal, &miss); |
745 __ bind(&fast); | 738 __ bind(&fast); |
746 // Check that the maps starting from the prototype haven't changed. | 739 // Check that the maps starting from the prototype haven't changed. |
747 GenerateLoadGlobalFunctionPrototype(masm(), | 740 GenerateLoadGlobalFunctionPrototype(masm(), |
748 Context::NUMBER_FUNCTION_INDEX, | 741 Context::NUMBER_FUNCTION_INDEX, |
749 rcx); | 742 rcx); |
750 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, | 743 CheckPrototypes(JSObject::cast(object->GetPrototype()), rcx, holder, |
751 rbx, rdx, name, &miss); | 744 rbx, rdx, name, &miss); |
752 break; | 745 break; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 // rsp[argc * 8] argument 1 | 816 // rsp[argc * 8] argument 1 |
824 // rsp[(argc + 1) * 8] argument 0 = receiver | 817 // rsp[(argc + 1) * 8] argument 0 = receiver |
825 // rsp[(argc + 2) * 8] function name | 818 // rsp[(argc + 2) * 8] function name |
826 Label miss; | 819 Label miss; |
827 | 820 |
828 // Get the receiver from the stack. | 821 // Get the receiver from the stack. |
829 const int argc = arguments().immediate(); | 822 const int argc = arguments().immediate(); |
830 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 823 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
831 | 824 |
832 // Check that the receiver isn't a smi. | 825 // Check that the receiver isn't a smi. |
833 __ testl(rdx, Immediate(kSmiTagMask)); | 826 __ JumpIfSmi(rdx, &miss); |
834 __ j(zero, &miss); | |
835 | 827 |
836 // Do the right check and compute the holder register. | 828 // Do the right check and compute the holder register. |
837 Register reg = | 829 Register reg = |
838 CheckPrototypes(JSObject::cast(object), rdx, holder, | 830 CheckPrototypes(JSObject::cast(object), rdx, holder, |
839 rbx, rcx, name, &miss); | 831 rbx, rcx, name, &miss); |
840 | 832 |
841 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index); | 833 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index); |
842 | 834 |
843 // Check that the function really is a function. | 835 // Check that the function really is a function. |
844 __ testl(rdi, Immediate(kSmiTagMask)); | 836 __ JumpIfSmi(rdi, &miss); |
845 __ j(zero, &miss); | |
846 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); | 837 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); |
847 __ j(not_equal, &miss); | 838 __ j(not_equal, &miss); |
848 | 839 |
849 // Patch the receiver on the stack with the global proxy if | 840 // Patch the receiver on the stack with the global proxy if |
850 // necessary. | 841 // necessary. |
851 if (object->IsGlobalObject()) { | 842 if (object->IsGlobalObject()) { |
852 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 843 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
853 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 844 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
854 } | 845 } |
855 | 846 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 &lookup, | 883 &lookup, |
893 rdx, | 884 rdx, |
894 rbx, | 885 rbx, |
895 rcx, | 886 rcx, |
896 &miss); | 887 &miss); |
897 | 888 |
898 // Restore receiver. | 889 // Restore receiver. |
899 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 890 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
900 | 891 |
901 // Check that the function really is a function. | 892 // Check that the function really is a function. |
902 __ testl(rax, Immediate(kSmiTagMask)); | 893 __ JumpIfSmi(rax, &miss); |
903 __ j(zero, &miss); | |
904 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); | 894 __ CmpObjectType(rax, JS_FUNCTION_TYPE, rbx); |
905 __ j(not_equal, &miss); | 895 __ j(not_equal, &miss); |
906 | 896 |
907 // Patch the receiver on the stack with the global proxy if | 897 // Patch the receiver on the stack with the global proxy if |
908 // necessary. | 898 // necessary. |
909 if (object->IsGlobalObject()) { | 899 if (object->IsGlobalObject()) { |
910 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 900 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
911 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 901 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
912 } | 902 } |
913 | 903 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 // Get the number of arguments. | 935 // Get the number of arguments. |
946 const int argc = arguments().immediate(); | 936 const int argc = arguments().immediate(); |
947 | 937 |
948 // Get the receiver from the stack. | 938 // Get the receiver from the stack. |
949 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 939 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
950 | 940 |
951 // If the object is the holder then we know that it's a global | 941 // If the object is the holder then we know that it's a global |
952 // object which can only happen for contextual calls. In this case, | 942 // object which can only happen for contextual calls. In this case, |
953 // the receiver cannot be a smi. | 943 // the receiver cannot be a smi. |
954 if (object != holder) { | 944 if (object != holder) { |
955 __ testl(rdx, Immediate(kSmiTagMask)); | 945 __ JumpIfSmi(rdx, &miss); |
956 __ j(zero, &miss); | |
957 } | 946 } |
958 | 947 |
959 // Check that the maps haven't changed. | 948 // Check that the maps haven't changed. |
960 CheckPrototypes(object, rdx, holder, rbx, rcx, name, &miss); | 949 CheckPrototypes(object, rdx, holder, rbx, rcx, name, &miss); |
961 | 950 |
962 // Get the value from the cell. | 951 // Get the value from the cell. |
963 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); | 952 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); |
964 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); | 953 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); |
965 | 954 |
966 // Check that the cell contains the same function. | 955 // Check that the cell contains the same function. |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 // ----------------------------------- | 1094 // ----------------------------------- |
1106 Label miss; | 1095 Label miss; |
1107 | 1096 |
1108 // Get the receiver from the stack. | 1097 // Get the receiver from the stack. |
1109 __ movq(rax, Operand(rsp, kPointerSize)); | 1098 __ movq(rax, Operand(rsp, kPointerSize)); |
1110 | 1099 |
1111 // If the object is the holder then we know that it's a global | 1100 // If the object is the holder then we know that it's a global |
1112 // object which can only happen for contextual loads. In this case, | 1101 // object which can only happen for contextual loads. In this case, |
1113 // the receiver cannot be a smi. | 1102 // the receiver cannot be a smi. |
1114 if (object != holder) { | 1103 if (object != holder) { |
1115 __ testl(rax, Immediate(kSmiTagMask)); | 1104 __ JumpIfSmi(rax, &miss); |
1116 __ j(zero, &miss); | |
1117 } | 1105 } |
1118 | 1106 |
1119 // Check that the maps haven't changed. | 1107 // Check that the maps haven't changed. |
1120 CheckPrototypes(object, rax, holder, rbx, rdx, name, &miss); | 1108 CheckPrototypes(object, rax, holder, rbx, rdx, name, &miss); |
1121 | 1109 |
1122 // Get the value from the cell. | 1110 // Get the value from the cell. |
1123 __ Move(rax, Handle<JSGlobalPropertyCell>(cell)); | 1111 __ Move(rax, Handle<JSGlobalPropertyCell>(cell)); |
1124 __ movq(rax, FieldOperand(rax, JSGlobalPropertyCell::kValueOffset)); | 1112 __ movq(rax, FieldOperand(rax, JSGlobalPropertyCell::kValueOffset)); |
1125 | 1113 |
1126 // Check for deleted property if property can actually be deleted. | 1114 // Check for deleted property if property can actually be deleted. |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1328 // -- rcx : name | 1316 // -- rcx : name |
1329 // -- rsp[0] : return address | 1317 // -- rsp[0] : return address |
1330 // -- rsp[8] : receiver | 1318 // -- rsp[8] : receiver |
1331 // ----------------------------------- | 1319 // ----------------------------------- |
1332 Label miss; | 1320 Label miss; |
1333 | 1321 |
1334 // Get the object from the stack. | 1322 // Get the object from the stack. |
1335 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); | 1323 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); |
1336 | 1324 |
1337 // Check that the object isn't a smi. | 1325 // Check that the object isn't a smi. |
1338 __ testl(rbx, Immediate(kSmiTagMask)); | 1326 __ JumpIfSmi(rbx, &miss); |
1339 __ j(zero, &miss); | |
1340 | 1327 |
1341 // Check that the map of the object hasn't changed. | 1328 // Check that the map of the object hasn't changed. |
1342 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), | 1329 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), |
1343 Handle<Map>(object->map())); | 1330 Handle<Map>(object->map())); |
1344 __ j(not_equal, &miss); | 1331 __ j(not_equal, &miss); |
1345 | 1332 |
1346 // Perform global security token check if needed. | 1333 // Perform global security token check if needed. |
1347 if (object->IsJSGlobalProxy()) { | 1334 if (object->IsJSGlobalProxy()) { |
1348 __ CheckAccessGlobalProxy(rbx, rdx, &miss); | 1335 __ CheckAccessGlobalProxy(rbx, rdx, &miss); |
1349 } | 1336 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1417 // -- rcx : name | 1404 // -- rcx : name |
1418 // -- rsp[0] : return address | 1405 // -- rsp[0] : return address |
1419 // -- rsp[8] : receiver | 1406 // -- rsp[8] : receiver |
1420 // ----------------------------------- | 1407 // ----------------------------------- |
1421 Label miss; | 1408 Label miss; |
1422 | 1409 |
1423 // Get the object from the stack. | 1410 // Get the object from the stack. |
1424 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); | 1411 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); |
1425 | 1412 |
1426 // Check that the object isn't a smi. | 1413 // Check that the object isn't a smi. |
1427 __ testl(rbx, Immediate(kSmiTagMask)); | 1414 __ JumpIfSmi(rbx, &miss); |
1428 __ j(zero, &miss); | |
1429 | 1415 |
1430 // Check that the map of the object hasn't changed. | 1416 // Check that the map of the object hasn't changed. |
1431 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), | 1417 __ Cmp(FieldOperand(rbx, HeapObject::kMapOffset), |
1432 Handle<Map>(receiver->map())); | 1418 Handle<Map>(receiver->map())); |
1433 __ j(not_equal, &miss); | 1419 __ j(not_equal, &miss); |
1434 | 1420 |
1435 // Perform global security token check if needed. | 1421 // Perform global security token check if needed. |
1436 if (receiver->IsJSGlobalProxy()) { | 1422 if (receiver->IsJSGlobalProxy()) { |
1437 __ CheckAccessGlobalProxy(rbx, rdx, &miss); | 1423 __ CheckAccessGlobalProxy(rbx, rdx, &miss); |
1438 } | 1424 } |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 void StubCompiler::GenerateLoadCallback(JSObject* object, | 1610 void StubCompiler::GenerateLoadCallback(JSObject* object, |
1625 JSObject* holder, | 1611 JSObject* holder, |
1626 Register receiver, | 1612 Register receiver, |
1627 Register name_reg, | 1613 Register name_reg, |
1628 Register scratch1, | 1614 Register scratch1, |
1629 Register scratch2, | 1615 Register scratch2, |
1630 AccessorInfo* callback, | 1616 AccessorInfo* callback, |
1631 String* name, | 1617 String* name, |
1632 Label* miss) { | 1618 Label* miss) { |
1633 // Check that the receiver isn't a smi. | 1619 // Check that the receiver isn't a smi. |
1634 __ testl(receiver, Immediate(kSmiTagMask)); | 1620 __ JumpIfSmi(receiver, miss); |
1635 __ j(zero, miss); | |
1636 | 1621 |
1637 // Check that the maps haven't changed. | 1622 // Check that the maps haven't changed. |
1638 Register reg = | 1623 Register reg = |
1639 CheckPrototypes(object, receiver, holder, | 1624 CheckPrototypes(object, receiver, holder, |
1640 scratch1, scratch2, name, miss); | 1625 scratch1, scratch2, name, miss); |
1641 | 1626 |
1642 // Push the arguments on the JS stack of the caller. | 1627 // Push the arguments on the JS stack of the caller. |
1643 __ pop(scratch2); // remove return address | 1628 __ pop(scratch2); // remove return address |
1644 __ push(receiver); // receiver | 1629 __ push(receiver); // receiver |
1645 __ push(reg); // holder | 1630 __ push(reg); // holder |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1694 | 1679 |
1695 void StubCompiler::GenerateLoadField(JSObject* object, | 1680 void StubCompiler::GenerateLoadField(JSObject* object, |
1696 JSObject* holder, | 1681 JSObject* holder, |
1697 Register receiver, | 1682 Register receiver, |
1698 Register scratch1, | 1683 Register scratch1, |
1699 Register scratch2, | 1684 Register scratch2, |
1700 int index, | 1685 int index, |
1701 String* name, | 1686 String* name, |
1702 Label* miss) { | 1687 Label* miss) { |
1703 // Check that the receiver isn't a smi. | 1688 // Check that the receiver isn't a smi. |
1704 __ testl(receiver, Immediate(kSmiTagMask)); | 1689 __ JumpIfSmi(receiver, miss); |
1705 __ j(zero, miss); | |
1706 | 1690 |
1707 // Check the prototype chain. | 1691 // Check the prototype chain. |
1708 Register reg = | 1692 Register reg = |
1709 CheckPrototypes(object, receiver, holder, | 1693 CheckPrototypes(object, receiver, holder, |
1710 scratch1, scratch2, name, miss); | 1694 scratch1, scratch2, name, miss); |
1711 | 1695 |
1712 // Get the value from the properties. | 1696 // Get the value from the properties. |
1713 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); | 1697 GenerateFastPropertyLoad(masm(), rax, reg, holder, index); |
1714 __ ret(0); | 1698 __ ret(0); |
1715 } | 1699 } |
1716 | 1700 |
1717 | 1701 |
1718 void StubCompiler::GenerateLoadConstant(JSObject* object, | 1702 void StubCompiler::GenerateLoadConstant(JSObject* object, |
1719 JSObject* holder, | 1703 JSObject* holder, |
1720 Register receiver, | 1704 Register receiver, |
1721 Register scratch1, | 1705 Register scratch1, |
1722 Register scratch2, | 1706 Register scratch2, |
1723 Object* value, | 1707 Object* value, |
1724 String* name, | 1708 String* name, |
1725 Label* miss) { | 1709 Label* miss) { |
1726 // Check that the receiver isn't a smi. | 1710 // Check that the receiver isn't a smi. |
1727 __ testl(receiver, Immediate(kSmiTagMask)); | 1711 __ JumpIfSmi(receiver, miss); |
1728 __ j(zero, miss); | |
1729 | 1712 |
1730 // Check that the maps haven't changed. | 1713 // Check that the maps haven't changed. |
1731 Register reg = | 1714 Register reg = |
1732 CheckPrototypes(object, receiver, holder, | 1715 CheckPrototypes(object, receiver, holder, |
1733 scratch1, scratch2, name, miss); | 1716 scratch1, scratch2, name, miss); |
1734 | 1717 |
1735 // Return the constant value. | 1718 // Return the constant value. |
1736 __ Move(rax, Handle<Object>(value)); | 1719 __ Move(rax, Handle<Object>(value)); |
1737 __ ret(0); | 1720 __ ret(0); |
1738 } | 1721 } |
(...skipping 20 matching lines...) Expand all Loading... |
1759 // code for the function thereby hitting the break points. | 1742 // code for the function thereby hitting the break points. |
1760 __ movq(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 1743 __ movq(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
1761 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kDebugInfoOffset)); | 1744 __ movq(rbx, FieldOperand(rbx, SharedFunctionInfo::kDebugInfoOffset)); |
1762 __ cmpq(rbx, r8); | 1745 __ cmpq(rbx, r8); |
1763 __ j(not_equal, &generic_stub_call); | 1746 __ j(not_equal, &generic_stub_call); |
1764 #endif | 1747 #endif |
1765 | 1748 |
1766 // Load the initial map and verify that it is in fact a map. | 1749 // Load the initial map and verify that it is in fact a map. |
1767 __ movq(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); | 1750 __ movq(rbx, FieldOperand(rdi, JSFunction::kPrototypeOrInitialMapOffset)); |
1768 // Will both indicate a NULL and a Smi. | 1751 // Will both indicate a NULL and a Smi. |
1769 __ testq(rbx, Immediate(kSmiTagMask)); | 1752 __ JumpIfSmi(rbx, &generic_stub_call); |
1770 __ j(zero, &generic_stub_call); | |
1771 __ CmpObjectType(rbx, MAP_TYPE, rcx); | 1753 __ CmpObjectType(rbx, MAP_TYPE, rcx); |
1772 __ j(not_equal, &generic_stub_call); | 1754 __ j(not_equal, &generic_stub_call); |
1773 | 1755 |
1774 #ifdef DEBUG | 1756 #ifdef DEBUG |
1775 // Cannot construct functions this way. | 1757 // Cannot construct functions this way. |
1776 // rdi: constructor | 1758 // rdi: constructor |
1777 // rbx: initial map | 1759 // rbx: initial map |
1778 __ CmpInstanceType(rbx, JS_FUNCTION_TYPE); | 1760 __ CmpInstanceType(rbx, JS_FUNCTION_TYPE); |
1779 __ Assert(not_equal, "Function constructed by construct stub."); | 1761 __ Assert(not_equal, "Function constructed by construct stub."); |
1780 #endif | 1762 #endif |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 1848 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
1867 | 1849 |
1868 // Return the generated code. | 1850 // Return the generated code. |
1869 return GetCode(); | 1851 return GetCode(); |
1870 } | 1852 } |
1871 | 1853 |
1872 | 1854 |
1873 #undef __ | 1855 #undef __ |
1874 | 1856 |
1875 } } // namespace v8::internal | 1857 } } // namespace v8::internal |
OLD | NEW |