Chromium Code Reviews| 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 |