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 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 __ JumpIfSmi(a0, &convert); | 935 __ JumpIfSmi(a0, &convert); |
936 __ GetObjectType(a0, a1, a1); | 936 __ GetObjectType(a0, a1, a1); |
937 __ Branch(&done_convert, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE)); | 937 __ Branch(&done_convert, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE)); |
938 __ bind(&convert); | 938 __ bind(&convert); |
939 __ push(a0); | 939 __ push(a0); |
940 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 940 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); |
941 __ mov(a0, v0); | 941 __ mov(a0, v0); |
942 __ bind(&done_convert); | 942 __ bind(&done_convert); |
943 __ push(a0); | 943 __ push(a0); |
944 | 944 |
| 945 // Check for proxies. |
| 946 Label call_runtime; |
| 947 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| 948 __ GetObjectType(a0, a1, a1); |
| 949 __ Branch(&call_runtime, le, a1, Operand(LAST_JS_PROXY_TYPE)); |
| 950 |
945 // Check cache validity in generated code. This is a fast case for | 951 // Check cache validity in generated code. This is a fast case for |
946 // the JSObject::IsSimpleEnum cache validity checks. If we cannot | 952 // the JSObject::IsSimpleEnum cache validity checks. If we cannot |
947 // guarantee cache validity, call the runtime system to check cache | 953 // guarantee cache validity, call the runtime system to check cache |
948 // validity or get the property names in a fixed array. | 954 // validity or get the property names in a fixed array. |
949 Label next, call_runtime; | 955 Label next; |
950 // Preload a couple of values used in the loop. | 956 // Preload a couple of values used in the loop. |
951 Register empty_fixed_array_value = t2; | 957 Register empty_fixed_array_value = t2; |
952 __ LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); | 958 __ LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); |
953 Register empty_descriptor_array_value = t3; | 959 Register empty_descriptor_array_value = t3; |
954 __ LoadRoot(empty_descriptor_array_value, | 960 __ LoadRoot(empty_descriptor_array_value, |
955 Heap::kEmptyDescriptorArrayRootIndex); | 961 Heap::kEmptyDescriptorArrayRootIndex); |
956 __ mov(a1, a0); | 962 __ mov(a1, a0); |
957 __ bind(&next); | 963 __ bind(&next); |
958 | 964 |
959 // Check that there are no elements. Register a1 contains the | 965 // Check that there are no elements. Register a1 contains the |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 | 1019 |
1014 // Setup the four remaining stack slots. | 1020 // Setup the four remaining stack slots. |
1015 __ push(v0); // Map. | 1021 __ push(v0); // Map. |
1016 __ lw(a1, FieldMemOperand(a2, FixedArray::kLengthOffset)); | 1022 __ lw(a1, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
1017 __ li(a0, Operand(Smi::FromInt(0))); | 1023 __ li(a0, Operand(Smi::FromInt(0))); |
1018 // Push enumeration cache, enumeration cache length (as smi) and zero. | 1024 // Push enumeration cache, enumeration cache length (as smi) and zero. |
1019 __ Push(a2, a1, a0); | 1025 __ Push(a2, a1, a0); |
1020 __ jmp(&loop); | 1026 __ jmp(&loop); |
1021 | 1027 |
1022 // We got a fixed array in register v0. Iterate through that. | 1028 // We got a fixed array in register v0. Iterate through that. |
| 1029 Label non_proxy; |
1023 __ bind(&fixed_array); | 1030 __ bind(&fixed_array); |
1024 __ li(a1, Operand(Smi::FromInt(0))); // Map (0) - force slow check. | 1031 __ li(a1, Operand(Smi::FromInt(1))); // Smi indicates slow check |
1025 __ Push(a1, v0); | 1032 __ lw(a2, MemOperand(sp, 0 * kPointerSize)); // Get enumerated object |
| 1033 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| 1034 __ GetObjectType(a2, a3, a3); |
| 1035 __ Branch(&non_proxy, gt, a3, Operand(LAST_JS_PROXY_TYPE)); |
| 1036 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy |
| 1037 __ bind(&non_proxy); |
| 1038 __ Push(a1, v0); // Smi and array |
1026 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); | 1039 __ lw(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); |
1027 __ li(a0, Operand(Smi::FromInt(0))); | 1040 __ li(a0, Operand(Smi::FromInt(0))); |
1028 __ Push(a1, a0); // Fixed array length (as smi) and initial index. | 1041 __ Push(a1, a0); // Fixed array length (as smi) and initial index. |
1029 | 1042 |
1030 // Generate code for doing the condition check. | 1043 // Generate code for doing the condition check. |
1031 __ bind(&loop); | 1044 __ bind(&loop); |
1032 // Load the current count to a0, load the length to a1. | 1045 // Load the current count to a0, load the length to a1. |
1033 __ lw(a0, MemOperand(sp, 0 * kPointerSize)); | 1046 __ lw(a0, MemOperand(sp, 0 * kPointerSize)); |
1034 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); | 1047 __ lw(a1, MemOperand(sp, 1 * kPointerSize)); |
1035 __ Branch(loop_statement.break_label(), hs, a0, Operand(a1)); | 1048 __ Branch(loop_statement.break_label(), hs, a0, Operand(a1)); |
1036 | 1049 |
1037 // Get the current entry of the array into register a3. | 1050 // Get the current entry of the array into register a3. |
1038 __ lw(a2, MemOperand(sp, 2 * kPointerSize)); | 1051 __ lw(a2, MemOperand(sp, 2 * kPointerSize)); |
1039 __ Addu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1052 __ Addu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1040 __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize); | 1053 __ sll(t0, a0, kPointerSizeLog2 - kSmiTagSize); |
1041 __ addu(t0, a2, t0); // Array base + scaled (smi) index. | 1054 __ addu(t0, a2, t0); // Array base + scaled (smi) index. |
1042 __ lw(a3, MemOperand(t0)); // Current entry. | 1055 __ lw(a3, MemOperand(t0)); // Current entry. |
1043 | 1056 |
1044 // Get the expected map from the stack or a zero map in the | 1057 // Get the expected map from the stack or a smi in the |
1045 // permanent slow case into register a2. | 1058 // permanent slow case into register a2. |
1046 __ lw(a2, MemOperand(sp, 3 * kPointerSize)); | 1059 __ lw(a2, MemOperand(sp, 3 * kPointerSize)); |
1047 | 1060 |
1048 // Check if the expected map still matches that of the enumerable. | 1061 // Check if the expected map still matches that of the enumerable. |
1049 // If not, we have to filter the key. | 1062 // If not, we may have to filter the key. |
1050 Label update_each; | 1063 Label update_each; |
1051 __ lw(a1, MemOperand(sp, 4 * kPointerSize)); | 1064 __ lw(a1, MemOperand(sp, 4 * kPointerSize)); |
1052 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); | 1065 __ lw(t0, FieldMemOperand(a1, HeapObject::kMapOffset)); |
1053 __ Branch(&update_each, eq, t0, Operand(a2)); | 1066 __ Branch(&update_each, eq, t0, Operand(a2)); |
1054 | 1067 |
| 1068 // For proxies, no filtering is done. |
| 1069 // TODO(rossberg): What if only a prototype is a proxy? Not specified yet. |
| 1070 ASSERT_EQ(Smi::FromInt(0), 0); |
| 1071 __ Branch(&update_each, eq, a2, Operand(zero_reg)); |
| 1072 |
1055 // Convert the entry to a string or (smi) 0 if it isn't a property | 1073 // Convert the entry to a string or (smi) 0 if it isn't a property |
1056 // any more. If the property has been removed while iterating, we | 1074 // any more. If the property has been removed while iterating, we |
1057 // just skip it. | 1075 // just skip it. |
1058 __ push(a1); // Enumerable. | 1076 __ push(a1); // Enumerable. |
1059 __ push(a3); // Current entry. | 1077 __ push(a3); // Current entry. |
1060 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); | 1078 __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); |
1061 __ mov(a3, result_register()); | 1079 __ mov(a3, result_register()); |
1062 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg)); | 1080 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg)); |
1063 | 1081 |
1064 // Update the 'each' property or variable from the possibly filtered | 1082 // Update the 'each' property or variable from the possibly filtered |
(...skipping 1782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2847 | 2865 |
2848 // Convert 32 random bits in v0 to 0.(32 random bits) in a double | 2866 // Convert 32 random bits in v0 to 0.(32 random bits) in a double |
2849 // by computing: | 2867 // by computing: |
2850 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | 2868 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
2851 if (CpuFeatures::IsSupported(FPU)) { | 2869 if (CpuFeatures::IsSupported(FPU)) { |
2852 __ PrepareCallCFunction(1, a0); | 2870 __ PrepareCallCFunction(1, a0); |
2853 __ lw(a0, ContextOperand(cp, Context::GLOBAL_INDEX)); | 2871 __ lw(a0, ContextOperand(cp, Context::GLOBAL_INDEX)); |
2854 __ lw(a0, FieldOperand(a0, GlobalObject::kGlobalContextOffset)); | 2872 __ lw(a0, FieldOperand(a0, GlobalObject::kGlobalContextOffset)); |
2855 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 2873 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
2856 | 2874 |
2857 | |
2858 CpuFeatures::Scope scope(FPU); | 2875 CpuFeatures::Scope scope(FPU); |
2859 // 0x41300000 is the top half of 1.0 x 2^20 as a double. | 2876 // 0x41300000 is the top half of 1.0 x 2^20 as a double. |
2860 __ li(a1, Operand(0x41300000)); | 2877 __ li(a1, Operand(0x41300000)); |
2861 // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. | 2878 // Move 0x41300000xxxxxxxx (x = random bits in v0) to FPU. |
2862 __ Move(f12, v0, a1); | 2879 __ Move(f12, v0, a1); |
2863 // Move 0x4130000000000000 to FPU. | 2880 // Move 0x4130000000000000 to FPU. |
2864 __ Move(f14, zero_reg, a1); | 2881 __ Move(f14, zero_reg, a1); |
2865 // Subtract and store the result in the heap number. | 2882 // Subtract and store the result in the heap number. |
2866 __ sub_d(f0, f12, f14); | 2883 __ sub_d(f0, f12, f14); |
2867 __ sdc1(f0, MemOperand(s0, HeapNumber::kValueOffset - kHeapObjectTag)); | 2884 __ sdc1(f0, MemOperand(s0, HeapNumber::kValueOffset - kHeapObjectTag)); |
(...skipping 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4336 *context_length = 0; | 4353 *context_length = 0; |
4337 return previous_; | 4354 return previous_; |
4338 } | 4355 } |
4339 | 4356 |
4340 | 4357 |
4341 #undef __ | 4358 #undef __ |
4342 | 4359 |
4343 } } // namespace v8::internal | 4360 } } // namespace v8::internal |
4344 | 4361 |
4345 #endif // V8_TARGET_ARCH_MIPS | 4362 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |