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 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 Label convert, done_convert; | 883 Label convert, done_convert; |
884 __ JumpIfSmi(rax, &convert); | 884 __ JumpIfSmi(rax, &convert); |
885 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); | 885 __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx); |
886 __ j(above_equal, &done_convert); | 886 __ j(above_equal, &done_convert); |
887 __ bind(&convert); | 887 __ bind(&convert); |
888 __ push(rax); | 888 __ push(rax); |
889 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 889 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
890 __ bind(&done_convert); | 890 __ bind(&done_convert); |
891 __ push(rax); | 891 __ push(rax); |
892 | 892 |
893 // Check for proxies. | |
894 Label call_runtime; | |
895 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | |
896 __ CmpObjectType(rax, LAST_JS_PROXY_TYPE, rcx); | |
897 __ j(below_equal, &call_runtime); | |
898 | |
893 // Check cache validity in generated code. This is a fast case for | 899 // Check cache validity in generated code. This is a fast case for |
894 // the JSObject::IsSimpleEnum cache validity checks. If we cannot | 900 // the JSObject::IsSimpleEnum cache validity checks. If we cannot |
895 // guarantee cache validity, call the runtime system to check cache | 901 // guarantee cache validity, call the runtime system to check cache |
896 // validity or get the property names in a fixed array. | 902 // validity or get the property names in a fixed array. |
897 Label next, call_runtime; | 903 Label next; |
898 Register empty_fixed_array_value = r8; | 904 Register empty_fixed_array_value = r8; |
899 __ LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); | 905 __ LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); |
900 Register empty_descriptor_array_value = r9; | 906 Register empty_descriptor_array_value = r9; |
901 __ LoadRoot(empty_descriptor_array_value, | 907 __ LoadRoot(empty_descriptor_array_value, |
902 Heap::kEmptyDescriptorArrayRootIndex); | 908 Heap::kEmptyDescriptorArrayRootIndex); |
903 __ movq(rcx, rax); | 909 __ movq(rcx, rax); |
904 __ bind(&next); | 910 __ bind(&next); |
905 | 911 |
906 // Check that there are no elements. Register rcx contains the | 912 // Check that there are no elements. Register rcx contains the |
907 // current JS object we've reached through the prototype chain. | 913 // current JS object we've reached through the prototype chain. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
963 | 969 |
964 // Setup the four remaining stack slots. | 970 // Setup the four remaining stack slots. |
965 __ push(rax); // Map. | 971 __ push(rax); // Map. |
966 __ push(rdx); // Enumeration cache. | 972 __ push(rdx); // Enumeration cache. |
967 __ movq(rax, FieldOperand(rdx, FixedArray::kLengthOffset)); | 973 __ movq(rax, FieldOperand(rdx, FixedArray::kLengthOffset)); |
968 __ push(rax); // Enumeration cache length (as smi). | 974 __ push(rax); // Enumeration cache length (as smi). |
969 __ Push(Smi::FromInt(0)); // Initial index. | 975 __ Push(Smi::FromInt(0)); // Initial index. |
970 __ jmp(&loop); | 976 __ jmp(&loop); |
971 | 977 |
972 // We got a fixed array in register rax. Iterate through that. | 978 // We got a fixed array in register rax. Iterate through that. |
979 Label non_proxy; | |
973 __ bind(&fixed_array); | 980 __ bind(&fixed_array); |
974 __ Push(Smi::FromInt(0)); // Map (0) - force slow check. | 981 __ Move(rbx, Smi::FromInt(1)); // smi indicates slow check |
982 __ movq(rcx, Operand(rsp, 0 * kPointerSize)); // Get enumerated object | |
983 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | |
984 __ CmpObjectType(rcx, LAST_JS_PROXY_TYPE, rcx); | |
985 __ j(above, &non_proxy); | |
986 __ Move(rbx, Smi::FromInt(0)); // zero indicates proxy | |
987 __ bind(&non_proxy); | |
988 __ push(rbx); // map or smi | |
975 __ push(rax); | 989 __ push(rax); |
Rico
2011/10/20 14:25:31
Add comment about what rax is
rossberg
2011/10/24 13:31:35
Done.
| |
976 __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset)); | 990 __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset)); |
977 __ push(rax); // Fixed array length (as smi). | 991 __ push(rax); // Fixed array length (as smi). |
978 __ Push(Smi::FromInt(0)); // Initial index. | 992 __ Push(Smi::FromInt(0)); // Initial index. |
979 | 993 |
980 // Generate code for doing the condition check. | 994 // Generate code for doing the condition check. |
981 __ bind(&loop); | 995 __ bind(&loop); |
982 __ movq(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. | 996 __ movq(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index. |
983 __ cmpq(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. | 997 __ cmpq(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length. |
984 __ j(above_equal, loop_statement.break_label()); | 998 __ j(above_equal, loop_statement.break_label()); |
985 | 999 |
986 // Get the current entry of the array into register rbx. | 1000 // Get the current entry of the array into register rbx. |
987 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); | 1001 __ movq(rbx, Operand(rsp, 2 * kPointerSize)); |
988 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2); | 1002 SmiIndex index = masm()->SmiToIndex(rax, rax, kPointerSizeLog2); |
989 __ movq(rbx, FieldOperand(rbx, | 1003 __ movq(rbx, FieldOperand(rbx, |
990 index.reg, | 1004 index.reg, |
991 index.scale, | 1005 index.scale, |
992 FixedArray::kHeaderSize)); | 1006 FixedArray::kHeaderSize)); |
993 | 1007 |
994 // Get the expected map from the stack or a zero map in the | 1008 // Get the expected map from the stack or a smi in the |
995 // permanent slow case into register rdx. | 1009 // permanent slow case into register rdx. |
996 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); | 1010 __ movq(rdx, Operand(rsp, 3 * kPointerSize)); |
997 | 1011 |
998 // Check if the expected map still matches that of the enumerable. | 1012 // Check if the expected map still matches that of the enumerable. |
999 // If not, we have to filter the key. | 1013 // If not, we may have to filter the key. |
1000 Label update_each; | 1014 Label update_each; |
1001 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); | 1015 __ movq(rcx, Operand(rsp, 4 * kPointerSize)); |
1002 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); | 1016 __ cmpq(rdx, FieldOperand(rcx, HeapObject::kMapOffset)); |
1003 __ j(equal, &update_each, Label::kNear); | 1017 __ j(equal, &update_each, Label::kNear); |
1004 | 1018 |
1019 // For proxies, no filtering is done. | |
1020 // TODO(rossberg): What if only a prototype is a proxy? Not specified. | |
1021 __ Cmp(rdx, Smi::FromInt(0)); | |
1022 __ j(equal, &update_each, Label::kNear); | |
1023 | |
1005 // Convert the entry to a string or null if it isn't a property | 1024 // Convert the entry to a string or null if it isn't a property |
1006 // anymore. If the property has been removed while iterating, we | 1025 // anymore. If the property has been removed while iterating, we |
1007 // just skip it. | 1026 // just skip it. |
1008 __ push(rcx); // Enumerable. | 1027 __ push(rcx); // Enumerable. |
1009 __ push(rbx); // Current entry. | 1028 __ push(rbx); // Current entry. |
1010 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); | 1029 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); |
1011 __ Cmp(rax, Smi::FromInt(0)); | 1030 __ Cmp(rax, Smi::FromInt(0)); |
1012 __ j(equal, loop_statement.continue_label()); | 1031 __ j(equal, loop_statement.continue_label()); |
1013 __ movq(rbx, rax); | 1032 __ movq(rbx, rax); |
1014 | 1033 |
(...skipping 3180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4195 *context_length = 0; | 4214 *context_length = 0; |
4196 return previous_; | 4215 return previous_; |
4197 } | 4216 } |
4198 | 4217 |
4199 | 4218 |
4200 #undef __ | 4219 #undef __ |
4201 | 4220 |
4202 } } // namespace v8::internal | 4221 } } // namespace v8::internal |
4203 | 4222 |
4204 #endif // V8_TARGET_ARCH_X64 | 4223 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |