| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 __ sub(ToRegister(left), ToOperand(right)); | 933 __ sub(ToRegister(left), ToOperand(right)); |
| 934 } | 934 } |
| 935 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 935 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 936 DeoptimizeIf(overflow, instr->environment()); | 936 DeoptimizeIf(overflow, instr->environment()); |
| 937 } | 937 } |
| 938 } | 938 } |
| 939 | 939 |
| 940 | 940 |
| 941 void LCodeGen::DoConstantI(LConstantI* instr) { | 941 void LCodeGen::DoConstantI(LConstantI* instr) { |
| 942 ASSERT(instr->result()->IsRegister()); | 942 ASSERT(instr->result()->IsRegister()); |
| 943 __ mov(ToRegister(instr->result()), instr->value()); | 943 __ Set(ToRegister(instr->result()), Immediate(instr->value())); |
| 944 } | 944 } |
| 945 | 945 |
| 946 | 946 |
| 947 void LCodeGen::DoConstantD(LConstantD* instr) { | 947 void LCodeGen::DoConstantD(LConstantD* instr) { |
| 948 ASSERT(instr->result()->IsDoubleRegister()); | 948 ASSERT(instr->result()->IsDoubleRegister()); |
| 949 XMMRegister res = ToDoubleRegister(instr->result()); | 949 XMMRegister res = ToDoubleRegister(instr->result()); |
| 950 double v = instr->value(); | 950 double v = instr->value(); |
| 951 // Use xor to produce +0.0 in a fast and compact way, but avoid to | 951 // Use xor to produce +0.0 in a fast and compact way, but avoid to |
| 952 // do so if the constant is -0.0. | 952 // do so if the constant is -0.0. |
| 953 if (BitCast<uint64_t, double>(v) == 0) { | 953 if (BitCast<uint64_t, double>(v) == 0) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 966 __ push_imm32(lower); | 966 __ push_imm32(lower); |
| 967 __ movdbl(res, Operand(esp, 0)); | 967 __ movdbl(res, Operand(esp, 0)); |
| 968 __ add(Operand(esp), Immediate(2 * kPointerSize)); | 968 __ add(Operand(esp), Immediate(2 * kPointerSize)); |
| 969 } | 969 } |
| 970 } | 970 } |
| 971 } | 971 } |
| 972 | 972 |
| 973 | 973 |
| 974 void LCodeGen::DoConstantT(LConstantT* instr) { | 974 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 975 ASSERT(instr->result()->IsRegister()); | 975 ASSERT(instr->result()->IsRegister()); |
| 976 __ mov(ToRegister(instr->result()), Immediate(instr->value())); | 976 __ Set(ToRegister(instr->result()), Immediate(instr->value())); |
| 977 } | 977 } |
| 978 | 978 |
| 979 | 979 |
| 980 void LCodeGen::DoArrayLength(LArrayLength* instr) { | 980 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { |
| 981 Register result = ToRegister(instr->result()); | 981 Register result = ToRegister(instr->result()); |
| 982 | 982 Register array = ToRegister(instr->input()); |
| 983 if (instr->hydrogen()->value()->IsLoadElements()) { | 983 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); |
| 984 // We load the length directly from the elements array. | |
| 985 Register elements = ToRegister(instr->input()); | |
| 986 __ mov(result, FieldOperand(elements, FixedArray::kLengthOffset)); | |
| 987 } else { | |
| 988 // Check that the receiver really is an array. | |
| 989 Register array = ToRegister(instr->input()); | |
| 990 Register temporary = ToRegister(instr->temporary()); | |
| 991 __ CmpObjectType(array, JS_ARRAY_TYPE, temporary); | |
| 992 DeoptimizeIf(not_equal, instr->environment()); | |
| 993 | |
| 994 // Load length directly from the array. | |
| 995 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); | |
| 996 } | |
| 997 } | 984 } |
| 998 | 985 |
| 999 | 986 |
| 987 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { |
| 988 Register result = ToRegister(instr->result()); |
| 989 Register array = ToRegister(instr->input()); |
| 990 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset)); |
| 991 } |
| 992 |
| 993 |
| 1000 void LCodeGen::DoValueOf(LValueOf* instr) { | 994 void LCodeGen::DoValueOf(LValueOf* instr) { |
| 1001 Register input = ToRegister(instr->input()); | 995 Register input = ToRegister(instr->input()); |
| 1002 Register result = ToRegister(instr->result()); | 996 Register result = ToRegister(instr->result()); |
| 1003 Register map = ToRegister(instr->temporary()); | 997 Register map = ToRegister(instr->temporary()); |
| 1004 ASSERT(input.is(result)); | 998 ASSERT(input.is(result)); |
| 1005 NearLabel done; | 999 NearLabel done; |
| 1006 // If the object is a smi return the object. | 1000 // If the object is a smi return the object. |
| 1007 __ test(input, Immediate(kSmiTagMask)); | 1001 __ test(input, Immediate(kSmiTagMask)); |
| 1008 __ j(zero, &done); | 1002 __ j(zero, &done); |
| 1009 | 1003 |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1830 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 1824 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
| 1831 ASSERT(ToRegister(instr->object()).is(eax)); | 1825 ASSERT(ToRegister(instr->object()).is(eax)); |
| 1832 ASSERT(ToRegister(instr->result()).is(eax)); | 1826 ASSERT(ToRegister(instr->result()).is(eax)); |
| 1833 | 1827 |
| 1834 __ mov(ecx, instr->name()); | 1828 __ mov(ecx, instr->name()); |
| 1835 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 1829 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 1836 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 1830 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 1837 } | 1831 } |
| 1838 | 1832 |
| 1839 | 1833 |
| 1834 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { |
| 1835 Register function = ToRegister(instr->function()); |
| 1836 Register temp = ToRegister(instr->temporary()); |
| 1837 Register result = ToRegister(instr->result()); |
| 1838 |
| 1839 // Check that the function really is a function. |
| 1840 __ CmpObjectType(function, JS_FUNCTION_TYPE, result); |
| 1841 DeoptimizeIf(not_equal, instr->environment()); |
| 1842 |
| 1843 // Check whether the function has an instance prototype. |
| 1844 NearLabel non_instance; |
| 1845 __ test_b(FieldOperand(result, Map::kBitFieldOffset), |
| 1846 1 << Map::kHasNonInstancePrototype); |
| 1847 __ j(not_zero, &non_instance); |
| 1848 |
| 1849 // Get the prototype or initial map from the function. |
| 1850 __ mov(result, |
| 1851 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); |
| 1852 |
| 1853 // Check that the function has a prototype or an initial map. |
| 1854 __ cmp(Operand(result), Immediate(Factory::the_hole_value())); |
| 1855 DeoptimizeIf(equal, instr->environment()); |
| 1856 |
| 1857 // If the function does not have an initial map, we're done. |
| 1858 NearLabel done; |
| 1859 __ CmpObjectType(result, MAP_TYPE, temp); |
| 1860 __ j(not_equal, &done); |
| 1861 |
| 1862 // Get the prototype from the initial map. |
| 1863 __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); |
| 1864 __ jmp(&done); |
| 1865 |
| 1866 // Non-instance prototype: Fetch prototype from constructor field |
| 1867 // in the function's map. |
| 1868 __ bind(&non_instance); |
| 1869 __ mov(result, FieldOperand(result, Map::kConstructorOffset)); |
| 1870 |
| 1871 // All done. |
| 1872 __ bind(&done); |
| 1873 } |
| 1874 |
| 1875 |
| 1840 void LCodeGen::DoLoadElements(LLoadElements* instr) { | 1876 void LCodeGen::DoLoadElements(LLoadElements* instr) { |
| 1841 ASSERT(instr->result()->Equals(instr->input())); | 1877 ASSERT(instr->result()->Equals(instr->input())); |
| 1842 Register reg = ToRegister(instr->input()); | 1878 Register reg = ToRegister(instr->input()); |
| 1843 __ mov(reg, FieldOperand(reg, JSObject::kElementsOffset)); | 1879 __ mov(reg, FieldOperand(reg, JSObject::kElementsOffset)); |
| 1844 if (FLAG_debug_code) { | 1880 if (FLAG_debug_code) { |
| 1845 NearLabel done; | 1881 NearLabel done; |
| 1846 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1882 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 1847 Immediate(Factory::fixed_array_map())); | 1883 Immediate(Factory::fixed_array_map())); |
| 1848 __ j(equal, &done); | 1884 __ j(equal, &done); |
| 1849 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1885 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| (...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2890 DeoptimizeIf(instr->condition(), instr->environment()); | 2926 DeoptimizeIf(instr->condition(), instr->environment()); |
| 2891 } | 2927 } |
| 2892 | 2928 |
| 2893 | 2929 |
| 2894 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { | 2930 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { |
| 2895 Register input = ToRegister(instr->input()); | 2931 Register input = ToRegister(instr->input()); |
| 2896 Register temp = ToRegister(instr->temp()); | 2932 Register temp = ToRegister(instr->temp()); |
| 2897 InstanceType first = instr->hydrogen()->first(); | 2933 InstanceType first = instr->hydrogen()->first(); |
| 2898 InstanceType last = instr->hydrogen()->last(); | 2934 InstanceType last = instr->hydrogen()->last(); |
| 2899 | 2935 |
| 2900 __ test(input, Immediate(kSmiTagMask)); | |
| 2901 DeoptimizeIf(zero, instr->environment()); | |
| 2902 | |
| 2903 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); | 2936 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); |
| 2904 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), | 2937 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), |
| 2905 static_cast<int8_t>(first)); | 2938 static_cast<int8_t>(first)); |
| 2906 | 2939 |
| 2907 // If there is only one type in the interval check for equality. | 2940 // If there is only one type in the interval check for equality. |
| 2908 if (first == last) { | 2941 if (first == last) { |
| 2909 DeoptimizeIf(not_equal, instr->environment()); | 2942 DeoptimizeIf(not_equal, instr->environment()); |
| 2910 } else { | 2943 } else { |
| 2911 DeoptimizeIf(below, instr->environment()); | 2944 DeoptimizeIf(below, instr->environment()); |
| 2912 // Omit check for the last type. | 2945 // Omit check for the last type. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3005 | 3038 |
| 3006 | 3039 |
| 3007 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 3040 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
| 3008 // Setup the parameters to the stub/runtime call. | 3041 // Setup the parameters to the stub/runtime call. |
| 3009 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3042 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3010 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); | 3043 __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); |
| 3011 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 3044 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); |
| 3012 __ push(Immediate(instr->hydrogen()->constant_properties())); | 3045 __ push(Immediate(instr->hydrogen()->constant_properties())); |
| 3013 __ push(Immediate(Smi::FromInt(instr->hydrogen()->fast_elements() ? 1 : 0))); | 3046 __ push(Immediate(Smi::FromInt(instr->hydrogen()->fast_elements() ? 1 : 0))); |
| 3014 | 3047 |
| 3015 // Pick the right runtime function or stub to call. | 3048 // Pick the right runtime function to call. |
| 3016 if (instr->hydrogen()->depth() > 1) { | 3049 if (instr->hydrogen()->depth() > 1) { |
| 3017 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); | 3050 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); |
| 3018 } else { | 3051 } else { |
| 3019 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); | 3052 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); |
| 3020 } | 3053 } |
| 3021 } | 3054 } |
| 3022 | 3055 |
| 3023 | 3056 |
| 3024 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 3057 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { |
| 3025 NearLabel materialized; | 3058 NearLabel materialized; |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3273 ASSERT(!environment->HasBeenRegistered()); | 3306 ASSERT(!environment->HasBeenRegistered()); |
| 3274 RegisterEnvironmentForDeoptimization(environment); | 3307 RegisterEnvironmentForDeoptimization(environment); |
| 3275 ASSERT(osr_pc_offset_ == -1); | 3308 ASSERT(osr_pc_offset_ == -1); |
| 3276 osr_pc_offset_ = masm()->pc_offset(); | 3309 osr_pc_offset_ = masm()->pc_offset(); |
| 3277 } | 3310 } |
| 3278 | 3311 |
| 3279 | 3312 |
| 3280 #undef __ | 3313 #undef __ |
| 3281 | 3314 |
| 3282 } } // namespace v8::internal | 3315 } } // namespace v8::internal |
| OLD | NEW |