| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 Register r0, | 65 Register r0, |
| 66 Register r1, | 66 Register r1, |
| 67 Label* miss) { | 67 Label* miss) { |
| 68 // Register usage: | 68 // Register usage: |
| 69 // receiver: holds the receiver on entry and is unchanged. | 69 // receiver: holds the receiver on entry and is unchanged. |
| 70 // r0: used to hold receiver instance type. | 70 // r0: used to hold receiver instance type. |
| 71 // Holds the property dictionary on fall through. | 71 // Holds the property dictionary on fall through. |
| 72 // r1: used to hold receivers map. | 72 // r1: used to hold receivers map. |
| 73 | 73 |
| 74 // Check that the receiver isn't a smi. | 74 // Check that the receiver isn't a smi. |
| 75 __ test(receiver, Immediate(kSmiTagMask)); | 75 __ JumpIfSmi(receiver, miss); |
| 76 __ j(zero, miss); | |
| 77 | 76 |
| 78 // Check that the receiver is a valid JS object. | 77 // Check that the receiver is a valid JS object. |
| 79 __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset)); | 78 __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 80 __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); | 79 __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); |
| 81 __ cmp(r0, FIRST_SPEC_OBJECT_TYPE); | 80 __ cmp(r0, FIRST_SPEC_OBJECT_TYPE); |
| 82 __ j(below, miss); | 81 __ j(below, miss); |
| 83 | 82 |
| 84 // If this assert fails, we have to check upper bound too. | 83 // If this assert fails, we have to check upper bound too. |
| 85 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | 84 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); |
| 86 | 85 |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 Register receiver, | 365 Register receiver, |
| 367 Register map, | 366 Register map, |
| 368 int interceptor_bit, | 367 int interceptor_bit, |
| 369 Label* slow) { | 368 Label* slow) { |
| 370 // Register use: | 369 // Register use: |
| 371 // receiver - holds the receiver and is unchanged. | 370 // receiver - holds the receiver and is unchanged. |
| 372 // Scratch registers: | 371 // Scratch registers: |
| 373 // map - used to hold the map of the receiver. | 372 // map - used to hold the map of the receiver. |
| 374 | 373 |
| 375 // Check that the object isn't a smi. | 374 // Check that the object isn't a smi. |
| 376 __ test(receiver, Immediate(kSmiTagMask)); | 375 __ JumpIfSmi(receiver, slow); |
| 377 __ j(zero, slow); | |
| 378 | 376 |
| 379 // Get the map of the receiver. | 377 // Get the map of the receiver. |
| 380 __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); | 378 __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 381 | 379 |
| 382 // Check bit field. | 380 // Check bit field. |
| 383 __ test_b(FieldOperand(map, Map::kBitFieldOffset), | 381 __ test_b(FieldOperand(map, Map::kBitFieldOffset), |
| 384 (1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)); | 382 (1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)); |
| 385 __ j(not_zero, slow); | 383 __ j(not_zero, slow); |
| 386 // Check that the object is some kind of JS object EXCEPT JS Value type. | 384 // Check that the object is some kind of JS object EXCEPT JS Value type. |
| 387 // In the case that the object is a value-wrapper object, | 385 // In the case that the object is a value-wrapper object, |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 466 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
| 469 // ----------- S t a t e ------------- | 467 // ----------- S t a t e ------------- |
| 470 // -- eax : key | 468 // -- eax : key |
| 471 // -- edx : receiver | 469 // -- edx : receiver |
| 472 // -- esp[0] : return address | 470 // -- esp[0] : return address |
| 473 // ----------------------------------- | 471 // ----------------------------------- |
| 474 Label slow, check_string, index_smi, index_string, property_array_property; | 472 Label slow, check_string, index_smi, index_string, property_array_property; |
| 475 Label probe_dictionary, check_number_dictionary; | 473 Label probe_dictionary, check_number_dictionary; |
| 476 | 474 |
| 477 // Check that the key is a smi. | 475 // Check that the key is a smi. |
| 478 __ test(eax, Immediate(kSmiTagMask)); | 476 __ JumpIfNotSmi(eax, &check_string); |
| 479 __ j(not_zero, &check_string); | |
| 480 __ bind(&index_smi); | 477 __ bind(&index_smi); |
| 481 // Now the key is known to be a smi. This place is also jumped to from | 478 // Now the key is known to be a smi. This place is also jumped to from |
| 482 // where a numeric string is converted to a smi. | 479 // where a numeric string is converted to a smi. |
| 483 | 480 |
| 484 GenerateKeyedLoadReceiverCheck( | 481 GenerateKeyedLoadReceiverCheck( |
| 485 masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); | 482 masm, edx, ecx, Map::kHasIndexedInterceptor, &slow); |
| 486 | 483 |
| 487 // Check the receiver's map to see if it has fast elements. | 484 // Check the receiver's map to see if it has fast elements. |
| 488 __ CheckFastElements(ecx, &check_number_dictionary); | 485 __ CheckFastElements(ecx, &check_number_dictionary); |
| 489 | 486 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 | 655 |
| 659 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 656 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |
| 660 // ----------- S t a t e ------------- | 657 // ----------- S t a t e ------------- |
| 661 // -- eax : key | 658 // -- eax : key |
| 662 // -- edx : receiver | 659 // -- edx : receiver |
| 663 // -- esp[0] : return address | 660 // -- esp[0] : return address |
| 664 // ----------------------------------- | 661 // ----------------------------------- |
| 665 Label slow; | 662 Label slow; |
| 666 | 663 |
| 667 // Check that the receiver isn't a smi. | 664 // Check that the receiver isn't a smi. |
| 668 __ test(edx, Immediate(kSmiTagMask)); | 665 __ JumpIfSmi(edx, &slow); |
| 669 __ j(zero, &slow); | |
| 670 | 666 |
| 671 // Check that the key is an array index, that is Uint32. | 667 // Check that the key is an array index, that is Uint32. |
| 672 __ test(eax, Immediate(kSmiTagMask | kSmiSignMask)); | 668 __ test(eax, Immediate(kSmiTagMask | kSmiSignMask)); |
| 673 __ j(not_zero, &slow); | 669 __ j(not_zero, &slow); |
| 674 | 670 |
| 675 // Get the map of the receiver. | 671 // Get the map of the receiver. |
| 676 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 672 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 677 | 673 |
| 678 // Check that it has indexed interceptor and access checks | 674 // Check that it has indexed interceptor and access checks |
| 679 // are not enabled for this object. | 675 // are not enabled for this object. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 703 StrictModeFlag strict_mode) { | 699 StrictModeFlag strict_mode) { |
| 704 // ----------- S t a t e ------------- | 700 // ----------- S t a t e ------------- |
| 705 // -- eax : value | 701 // -- eax : value |
| 706 // -- ecx : key | 702 // -- ecx : key |
| 707 // -- edx : receiver | 703 // -- edx : receiver |
| 708 // -- esp[0] : return address | 704 // -- esp[0] : return address |
| 709 // ----------------------------------- | 705 // ----------------------------------- |
| 710 Label slow, fast, array, extra; | 706 Label slow, fast, array, extra; |
| 711 | 707 |
| 712 // Check that the object isn't a smi. | 708 // Check that the object isn't a smi. |
| 713 __ test(edx, Immediate(kSmiTagMask)); | 709 __ JumpIfSmi(edx, &slow); |
| 714 __ j(zero, &slow); | |
| 715 // Get the map from the receiver. | 710 // Get the map from the receiver. |
| 716 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 711 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); |
| 717 // Check that the receiver does not require access checks. We need | 712 // Check that the receiver does not require access checks. We need |
| 718 // to do this because this generic stub does not perform map checks. | 713 // to do this because this generic stub does not perform map checks. |
| 719 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), | 714 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), |
| 720 1 << Map::kIsAccessCheckNeeded); | 715 1 << Map::kIsAccessCheckNeeded); |
| 721 __ j(not_zero, &slow); | 716 __ j(not_zero, &slow); |
| 722 // Check that the key is a smi. | 717 // Check that the key is a smi. |
| 723 __ test(ecx, Immediate(kSmiTagMask)); | 718 __ JumpIfNotSmi(ecx, &slow); |
| 724 __ j(not_zero, &slow); | |
| 725 __ CmpInstanceType(edi, JS_ARRAY_TYPE); | 719 __ CmpInstanceType(edi, JS_ARRAY_TYPE); |
| 726 __ j(equal, &array); | 720 __ j(equal, &array); |
| 727 // Check that the object is some kind of JSObject. | 721 // Check that the object is some kind of JSObject. |
| 728 __ CmpInstanceType(edi, FIRST_JS_RECEIVER_TYPE); | 722 __ CmpInstanceType(edi, FIRST_JS_RECEIVER_TYPE); |
| 729 __ j(below, &slow); | 723 __ j(below, &slow); |
| 730 __ CmpInstanceType(edi, JS_PROXY_TYPE); | 724 __ CmpInstanceType(edi, JS_PROXY_TYPE); |
| 731 __ j(equal, &slow); | 725 __ j(equal, &slow); |
| 732 __ CmpInstanceType(edi, JS_FUNCTION_PROXY_TYPE); | 726 __ CmpInstanceType(edi, JS_FUNCTION_PROXY_TYPE); |
| 733 __ j(equal, &slow); | 727 __ j(equal, &slow); |
| 734 | 728 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 argc); | 808 argc); |
| 815 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, | 809 Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, |
| 816 eax); | 810 eax); |
| 817 | 811 |
| 818 // If the stub cache probing failed, the receiver might be a value. | 812 // If the stub cache probing failed, the receiver might be a value. |
| 819 // For value objects, we use the map of the prototype objects for | 813 // For value objects, we use the map of the prototype objects for |
| 820 // the corresponding JSValue for the cache and that is what we need | 814 // the corresponding JSValue for the cache and that is what we need |
| 821 // to probe. | 815 // to probe. |
| 822 // | 816 // |
| 823 // Check for number. | 817 // Check for number. |
| 824 __ test(edx, Immediate(kSmiTagMask)); | 818 __ JumpIfSmi(edx, &number); |
| 825 __ j(zero, &number); | |
| 826 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ebx); | 819 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, ebx); |
| 827 __ j(not_equal, &non_number); | 820 __ j(not_equal, &non_number); |
| 828 __ bind(&number); | 821 __ bind(&number); |
| 829 StubCompiler::GenerateLoadGlobalFunctionPrototype( | 822 StubCompiler::GenerateLoadGlobalFunctionPrototype( |
| 830 masm, Context::NUMBER_FUNCTION_INDEX, edx); | 823 masm, Context::NUMBER_FUNCTION_INDEX, edx); |
| 831 __ jmp(&probe); | 824 __ jmp(&probe); |
| 832 | 825 |
| 833 // Check for string. | 826 // Check for string. |
| 834 __ bind(&non_number); | 827 __ bind(&non_number); |
| 835 __ CmpInstanceType(ebx, FIRST_NONSTRING_TYPE); | 828 __ CmpInstanceType(ebx, FIRST_NONSTRING_TYPE); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 862 // ----------- S t a t e ------------- | 855 // ----------- S t a t e ------------- |
| 863 // -- ecx : name | 856 // -- ecx : name |
| 864 // -- edi : function | 857 // -- edi : function |
| 865 // -- esp[0] : return address | 858 // -- esp[0] : return address |
| 866 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 859 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 867 // -- ... | 860 // -- ... |
| 868 // -- esp[(argc + 1) * 4] : receiver | 861 // -- esp[(argc + 1) * 4] : receiver |
| 869 // ----------------------------------- | 862 // ----------------------------------- |
| 870 | 863 |
| 871 // Check that the result is not a smi. | 864 // Check that the result is not a smi. |
| 872 __ test(edi, Immediate(kSmiTagMask)); | 865 __ JumpIfSmi(edi, miss); |
| 873 __ j(zero, miss); | |
| 874 | 866 |
| 875 // Check that the value is a JavaScript function, fetching its map into eax. | 867 // Check that the value is a JavaScript function, fetching its map into eax. |
| 876 __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax); | 868 __ CmpObjectType(edi, JS_FUNCTION_TYPE, eax); |
| 877 __ j(not_equal, miss); | 869 __ j(not_equal, miss); |
| 878 | 870 |
| 879 // Invoke the function. | 871 // Invoke the function. |
| 880 ParameterCount actual(argc); | 872 ParameterCount actual(argc); |
| 881 __ InvokeFunction(edi, actual, JUMP_FUNCTION, | 873 __ InvokeFunction(edi, actual, JUMP_FUNCTION, |
| 882 NullCallWrapper(), CALL_AS_METHOD); | 874 NullCallWrapper(), CALL_AS_METHOD); |
| 883 } | 875 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 | 936 |
| 945 // Move result to edi and exit the internal frame. | 937 // Move result to edi and exit the internal frame. |
| 946 __ mov(edi, eax); | 938 __ mov(edi, eax); |
| 947 __ LeaveInternalFrame(); | 939 __ LeaveInternalFrame(); |
| 948 | 940 |
| 949 // Check if the receiver is a global object of some sort. | 941 // Check if the receiver is a global object of some sort. |
| 950 // This can happen only for regular CallIC but not KeyedCallIC. | 942 // This can happen only for regular CallIC but not KeyedCallIC. |
| 951 if (id == IC::kCallIC_Miss) { | 943 if (id == IC::kCallIC_Miss) { |
| 952 Label invoke, global; | 944 Label invoke, global; |
| 953 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver | 945 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); // receiver |
| 954 __ test(edx, Immediate(kSmiTagMask)); | 946 __ JumpIfSmi(edx, &invoke, Label::kNear); |
| 955 __ j(zero, &invoke, Label::kNear); | |
| 956 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); | 947 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 957 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 948 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 958 __ cmp(ebx, JS_GLOBAL_OBJECT_TYPE); | 949 __ cmp(ebx, JS_GLOBAL_OBJECT_TYPE); |
| 959 __ j(equal, &global, Label::kNear); | 950 __ j(equal, &global, Label::kNear); |
| 960 __ cmp(ebx, JS_BUILTINS_OBJECT_TYPE); | 951 __ cmp(ebx, JS_BUILTINS_OBJECT_TYPE); |
| 961 __ j(not_equal, &invoke, Label::kNear); | 952 __ j(not_equal, &invoke, Label::kNear); |
| 962 | 953 |
| 963 // Patch the receiver on the stack. | 954 // Patch the receiver on the stack. |
| 964 __ bind(&global); | 955 __ bind(&global); |
| 965 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 956 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 // ----------------------------------- | 1029 // ----------------------------------- |
| 1039 | 1030 |
| 1040 // Get the receiver of the function from the stack; 1 ~ return address. | 1031 // Get the receiver of the function from the stack; 1 ~ return address. |
| 1041 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1032 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 1042 | 1033 |
| 1043 Label do_call, slow_call, slow_load, slow_reload_receiver; | 1034 Label do_call, slow_call, slow_load, slow_reload_receiver; |
| 1044 Label check_number_dictionary, check_string, lookup_monomorphic_cache; | 1035 Label check_number_dictionary, check_string, lookup_monomorphic_cache; |
| 1045 Label index_smi, index_string; | 1036 Label index_smi, index_string; |
| 1046 | 1037 |
| 1047 // Check that the key is a smi. | 1038 // Check that the key is a smi. |
| 1048 __ test(ecx, Immediate(kSmiTagMask)); | 1039 __ JumpIfNotSmi(ecx, &check_string); |
| 1049 __ j(not_zero, &check_string); | |
| 1050 | 1040 |
| 1051 __ bind(&index_smi); | 1041 __ bind(&index_smi); |
| 1052 // Now the key is known to be a smi. This place is also jumped to from | 1042 // Now the key is known to be a smi. This place is also jumped to from |
| 1053 // where a numeric string is converted to a smi. | 1043 // where a numeric string is converted to a smi. |
| 1054 | 1044 |
| 1055 GenerateKeyedLoadReceiverCheck( | 1045 GenerateKeyedLoadReceiverCheck( |
| 1056 masm, edx, eax, Map::kHasIndexedInterceptor, &slow_call); | 1046 masm, edx, eax, Map::kHasIndexedInterceptor, &slow_call); |
| 1057 | 1047 |
| 1058 GenerateFastArrayLoad( | 1048 GenerateFastArrayLoad( |
| 1059 masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); | 1049 masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 // ----------- S t a t e ------------- | 1140 // ----------- S t a t e ------------- |
| 1151 // -- ecx : name | 1141 // -- ecx : name |
| 1152 // -- esp[0] : return address | 1142 // -- esp[0] : return address |
| 1153 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1143 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
| 1154 // -- ... | 1144 // -- ... |
| 1155 // -- esp[(argc + 1) * 4] : receiver | 1145 // -- esp[(argc + 1) * 4] : receiver |
| 1156 // ----------------------------------- | 1146 // ----------------------------------- |
| 1157 | 1147 |
| 1158 // Check if the name is a string. | 1148 // Check if the name is a string. |
| 1159 Label miss; | 1149 Label miss; |
| 1160 __ test(ecx, Immediate(kSmiTagMask)); | 1150 __ JumpIfSmi(ecx, &miss); |
| 1161 __ j(zero, &miss); | |
| 1162 Condition cond = masm->IsObjectStringType(ecx, eax, eax); | 1151 Condition cond = masm->IsObjectStringType(ecx, eax, eax); |
| 1163 __ j(NegateCondition(cond), &miss); | 1152 __ j(NegateCondition(cond), &miss); |
| 1164 GenerateCallNormal(masm, argc); | 1153 GenerateCallNormal(masm, argc); |
| 1165 __ bind(&miss); | 1154 __ bind(&miss); |
| 1166 GenerateMiss(masm, argc); | 1155 GenerateMiss(masm, argc); |
| 1167 } | 1156 } |
| 1168 | 1157 |
| 1169 | 1158 |
| 1170 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { | 1159 void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { |
| 1171 // ----------- S t a t e ------------- | 1160 // ----------- S t a t e ------------- |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1336 // elements of FixedArray type.), but currently is restricted to JSArray. | 1325 // elements of FixedArray type.), but currently is restricted to JSArray. |
| 1337 // Value must be a number, but only smis are accepted as the most common case. | 1326 // Value must be a number, but only smis are accepted as the most common case. |
| 1338 | 1327 |
| 1339 Label miss; | 1328 Label miss; |
| 1340 | 1329 |
| 1341 Register receiver = edx; | 1330 Register receiver = edx; |
| 1342 Register value = eax; | 1331 Register value = eax; |
| 1343 Register scratch = ebx; | 1332 Register scratch = ebx; |
| 1344 | 1333 |
| 1345 // Check that the receiver isn't a smi. | 1334 // Check that the receiver isn't a smi. |
| 1346 __ test(receiver, Immediate(kSmiTagMask)); | 1335 __ JumpIfSmi(receiver, &miss); |
| 1347 __ j(zero, &miss); | |
| 1348 | 1336 |
| 1349 // Check that the object is a JS array. | 1337 // Check that the object is a JS array. |
| 1350 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); | 1338 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); |
| 1351 __ j(not_equal, &miss); | 1339 __ j(not_equal, &miss); |
| 1352 | 1340 |
| 1353 // Check that elements are FixedArray. | 1341 // Check that elements are FixedArray. |
| 1354 // We rely on StoreIC_ArrayLength below to deal with all types of | 1342 // We rely on StoreIC_ArrayLength below to deal with all types of |
| 1355 // fast elements (including COW). | 1343 // fast elements (including COW). |
| 1356 __ mov(scratch, FieldOperand(receiver, JSArray::kElementsOffset)); | 1344 __ mov(scratch, FieldOperand(receiver, JSArray::kElementsOffset)); |
| 1357 __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch); | 1345 __ CmpObjectType(scratch, FIXED_ARRAY_TYPE, scratch); |
| 1358 __ j(not_equal, &miss); | 1346 __ j(not_equal, &miss); |
| 1359 | 1347 |
| 1360 // Check that value is a smi. | 1348 // Check that value is a smi. |
| 1361 __ test(value, Immediate(kSmiTagMask)); | 1349 __ JumpIfNotSmi(value, &miss); |
| 1362 __ j(not_zero, &miss); | |
| 1363 | 1350 |
| 1364 // Prepare tail call to StoreIC_ArrayLength. | 1351 // Prepare tail call to StoreIC_ArrayLength. |
| 1365 __ pop(scratch); | 1352 __ pop(scratch); |
| 1366 __ push(receiver); | 1353 __ push(receiver); |
| 1367 __ push(value); | 1354 __ push(value); |
| 1368 __ push(scratch); // return address | 1355 __ push(scratch); // return address |
| 1369 | 1356 |
| 1370 ExternalReference ref = | 1357 ExternalReference ref = |
| 1371 ExternalReference(IC_Utility(kStoreIC_ArrayLength), masm->isolate()); | 1358 ExternalReference(IC_Utility(kStoreIC_ArrayLength), masm->isolate()); |
| 1372 __ TailCallExternalReference(ref, 2, 1); | 1359 __ TailCallExternalReference(ref, 2, 1); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1590 Condition cc = *jmp_address == Assembler::kJncShortOpcode | 1577 Condition cc = *jmp_address == Assembler::kJncShortOpcode |
| 1591 ? not_zero | 1578 ? not_zero |
| 1592 : zero; | 1579 : zero; |
| 1593 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1580 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 1594 } | 1581 } |
| 1595 | 1582 |
| 1596 | 1583 |
| 1597 } } // namespace v8::internal | 1584 } } // namespace v8::internal |
| 1598 | 1585 |
| 1599 #endif // V8_TARGET_ARCH_IA32 | 1586 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |