| 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 |