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 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 | 942 |
943 // Assert that heap_number_result is callee-saved. | 943 // Assert that heap_number_result is callee-saved. |
944 // We currently always use r5 to pass it. | 944 // We currently always use r5 to pass it. |
945 ASSERT(heap_number_result.is(r5)); | 945 ASSERT(heap_number_result.is(r5)); |
946 | 946 |
947 // Push the current return address before the C call. Return will be | 947 // Push the current return address before the C call. Return will be |
948 // through pop(pc) below. | 948 // through pop(pc) below. |
949 __ push(lr); | 949 __ push(lr); |
950 __ PrepareCallCFunction(4, scratch); // Two doubles are 4 arguments. | 950 __ PrepareCallCFunction(4, scratch); // Two doubles are 4 arguments. |
951 // Call C routine that may not cause GC or other trouble. | 951 // Call C routine that may not cause GC or other trouble. |
952 __ CallCFunction(ExternalReference::double_fp_operation(op), 4); | 952 __ CallCFunction(ExternalReference::double_fp_operation(op, masm->isolate()), |
| 953 4); |
953 // Store answer in the overwritable heap number. | 954 // Store answer in the overwritable heap number. |
954 #if !defined(USE_ARM_EABI) | 955 #if !defined(USE_ARM_EABI) |
955 // Double returned in fp coprocessor register 0 and 1, encoded as | 956 // Double returned in fp coprocessor register 0 and 1, encoded as |
956 // register cr8. Offsets must be divisible by 4 for coprocessor so we | 957 // register cr8. Offsets must be divisible by 4 for coprocessor so we |
957 // need to substract the tag from heap_number_result. | 958 // need to substract the tag from heap_number_result. |
958 __ sub(scratch, heap_number_result, Operand(kHeapObjectTag)); | 959 __ sub(scratch, heap_number_result, Operand(kHeapObjectTag)); |
959 __ stc(p1, cr8, MemOperand(scratch, HeapNumber::kValueOffset)); | 960 __ stc(p1, cr8, MemOperand(scratch, HeapNumber::kValueOffset)); |
960 #else | 961 #else |
961 // Double returned in registers 0 and 1. | 962 // Double returned in registers 0 and 1. |
962 __ Strd(r0, r1, FieldMemOperand(heap_number_result, | 963 __ Strd(r0, r1, FieldMemOperand(heap_number_result, |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 __ Ret(ne); | 1298 __ Ret(ne); |
1298 // Now they are equal if and only if the lhs exponent is zero in its | 1299 // Now they are equal if and only if the lhs exponent is zero in its |
1299 // low 31 bits. | 1300 // low 31 bits. |
1300 __ mov(r0, Operand(rhs_exponent, LSL, kSmiTagSize)); | 1301 __ mov(r0, Operand(rhs_exponent, LSL, kSmiTagSize)); |
1301 __ Ret(); | 1302 __ Ret(); |
1302 } else { | 1303 } else { |
1303 // Call a native function to do a comparison between two non-NaNs. | 1304 // Call a native function to do a comparison between two non-NaNs. |
1304 // Call C routine that may not cause GC or other trouble. | 1305 // Call C routine that may not cause GC or other trouble. |
1305 __ push(lr); | 1306 __ push(lr); |
1306 __ PrepareCallCFunction(4, r5); // Two doubles count as 4 arguments. | 1307 __ PrepareCallCFunction(4, r5); // Two doubles count as 4 arguments. |
1307 __ CallCFunction(ExternalReference::compare_doubles(), 4); | 1308 __ CallCFunction(ExternalReference::compare_doubles(masm->isolate()), 4); |
1308 __ pop(pc); // Return. | 1309 __ pop(pc); // Return. |
1309 } | 1310 } |
1310 } | 1311 } |
1311 | 1312 |
1312 | 1313 |
1313 // See comment at call site. | 1314 // See comment at call site. |
1314 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, | 1315 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, |
1315 Register lhs, | 1316 Register lhs, |
1316 Register rhs) { | 1317 Register rhs) { |
1317 ASSERT((lhs.is(r0) && rhs.is(r1)) || | 1318 ASSERT((lhs.is(r0) && rhs.is(r1)) || |
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2011 // r0: Left value (least significant part of mantissa). | 2012 // r0: Left value (least significant part of mantissa). |
2012 // r1: Left value (sign, exponent, top of mantissa). | 2013 // r1: Left value (sign, exponent, top of mantissa). |
2013 // r2: Right value (least significant part of mantissa). | 2014 // r2: Right value (least significant part of mantissa). |
2014 // r3: Right value (sign, exponent, top of mantissa). | 2015 // r3: Right value (sign, exponent, top of mantissa). |
2015 // r5: Address of heap number for result. | 2016 // r5: Address of heap number for result. |
2016 | 2017 |
2017 __ push(lr); // For later. | 2018 __ push(lr); // For later. |
2018 __ PrepareCallCFunction(4, r4); // Two doubles count as 4 arguments. | 2019 __ PrepareCallCFunction(4, r4); // Two doubles count as 4 arguments. |
2019 // Call C routine that may not cause GC or other trouble. r5 is callee | 2020 // Call C routine that may not cause GC or other trouble. r5 is callee |
2020 // save. | 2021 // save. |
2021 __ CallCFunction(ExternalReference::double_fp_operation(op_), 4); | 2022 __ CallCFunction( |
| 2023 ExternalReference::double_fp_operation(op_, masm->isolate()), 4); |
2022 // Store answer in the overwritable heap number. | 2024 // Store answer in the overwritable heap number. |
2023 #if !defined(USE_ARM_EABI) | 2025 #if !defined(USE_ARM_EABI) |
2024 // Double returned in fp coprocessor register 0 and 1, encoded as | 2026 // Double returned in fp coprocessor register 0 and 1, encoded as |
2025 // register cr8. Offsets must be divisible by 4 for coprocessor so we | 2027 // register cr8. Offsets must be divisible by 4 for coprocessor so we |
2026 // need to substract the tag from r5. | 2028 // need to substract the tag from r5. |
2027 __ sub(r4, r5, Operand(kHeapObjectTag)); | 2029 __ sub(r4, r5, Operand(kHeapObjectTag)); |
2028 __ stc(p1, cr8, MemOperand(r4, HeapNumber::kValueOffset)); | 2030 __ stc(p1, cr8, MemOperand(r4, HeapNumber::kValueOffset)); |
2029 #else | 2031 #else |
2030 // Double returned in registers 0 and 1. | 2032 // Double returned in registers 0 and 1. |
2031 __ Strd(r0, r1, FieldMemOperand(r5, HeapNumber::kValueOffset)); | 2033 __ Strd(r0, r1, FieldMemOperand(r5, HeapNumber::kValueOffset)); |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2815 Label get_result; | 2817 Label get_result; |
2816 | 2818 |
2817 __ Push(r1, r0); | 2819 __ Push(r1, r0); |
2818 | 2820 |
2819 __ mov(r2, Operand(Smi::FromInt(MinorKey()))); | 2821 __ mov(r2, Operand(Smi::FromInt(MinorKey()))); |
2820 __ mov(r1, Operand(Smi::FromInt(op_))); | 2822 __ mov(r1, Operand(Smi::FromInt(op_))); |
2821 __ mov(r0, Operand(Smi::FromInt(runtime_operands_type_))); | 2823 __ mov(r0, Operand(Smi::FromInt(runtime_operands_type_))); |
2822 __ Push(r2, r1, r0); | 2824 __ Push(r2, r1, r0); |
2823 | 2825 |
2824 __ TailCallExternalReference( | 2826 __ TailCallExternalReference( |
2825 ExternalReference(IC_Utility(IC::kBinaryOp_Patch)), | 2827 ExternalReference(IC_Utility(IC::kBinaryOp_Patch), masm->isolate()), |
2826 5, | 2828 5, |
2827 1); | 2829 1); |
2828 } | 2830 } |
2829 | 2831 |
2830 | 2832 |
2831 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { | 2833 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { |
2832 GenericBinaryOpStub stub(key, type_info); | 2834 GenericBinaryOpStub stub(key, type_info); |
2833 return stub.GetCode(); | 2835 return stub.GetCode(); |
2834 } | 2836 } |
2835 | 2837 |
(...skipping 10 matching lines...) Expand all Loading... |
2846 Label get_result; | 2848 Label get_result; |
2847 | 2849 |
2848 __ Push(r1, r0); | 2850 __ Push(r1, r0); |
2849 | 2851 |
2850 __ mov(r2, Operand(Smi::FromInt(MinorKey()))); | 2852 __ mov(r2, Operand(Smi::FromInt(MinorKey()))); |
2851 __ mov(r1, Operand(Smi::FromInt(op_))); | 2853 __ mov(r1, Operand(Smi::FromInt(op_))); |
2852 __ mov(r0, Operand(Smi::FromInt(operands_type_))); | 2854 __ mov(r0, Operand(Smi::FromInt(operands_type_))); |
2853 __ Push(r2, r1, r0); | 2855 __ Push(r2, r1, r0); |
2854 | 2856 |
2855 __ TailCallExternalReference( | 2857 __ TailCallExternalReference( |
2856 ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch)), | 2858 ExternalReference(IC_Utility(IC::kTypeRecordingBinaryOp_Patch), |
| 2859 masm->isolate()), |
2857 5, | 2860 5, |
2858 1); | 2861 1); |
2859 } | 2862 } |
2860 | 2863 |
2861 | 2864 |
2862 void TypeRecordingBinaryOpStub::GenerateTypeTransitionWithSavedArgs( | 2865 void TypeRecordingBinaryOpStub::GenerateTypeTransitionWithSavedArgs( |
2863 MacroAssembler* masm) { | 2866 MacroAssembler* masm) { |
2864 UNIMPLEMENTED(); | 2867 UNIMPLEMENTED(); |
2865 } | 2868 } |
2866 | 2869 |
(...skipping 923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3790 // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1); | 3793 // h = (low ^ high); h ^= h >> 16; h ^= h >> 8; h = h & (cacheSize - 1); |
3791 __ eor(r1, r2, Operand(r3)); | 3794 __ eor(r1, r2, Operand(r3)); |
3792 __ eor(r1, r1, Operand(r1, ASR, 16)); | 3795 __ eor(r1, r1, Operand(r1, ASR, 16)); |
3793 __ eor(r1, r1, Operand(r1, ASR, 8)); | 3796 __ eor(r1, r1, Operand(r1, ASR, 8)); |
3794 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); | 3797 ASSERT(IsPowerOf2(TranscendentalCache::SubCache::kCacheSize)); |
3795 __ And(r1, r1, Operand(TranscendentalCache::SubCache::kCacheSize - 1)); | 3798 __ And(r1, r1, Operand(TranscendentalCache::SubCache::kCacheSize - 1)); |
3796 | 3799 |
3797 // r2 = low 32 bits of double value. | 3800 // r2 = low 32 bits of double value. |
3798 // r3 = high 32 bits of double value. | 3801 // r3 = high 32 bits of double value. |
3799 // r1 = TranscendentalCache::hash(double value). | 3802 // r1 = TranscendentalCache::hash(double value). |
3800 __ mov(cache_entry, | 3803 Isolate* isolate = masm->isolate(); |
3801 Operand(ExternalReference::transcendental_cache_array_address())); | 3804 ExternalReference cache_array = |
3802 // r0 points to cache array. | 3805 ExternalReference::transcendental_cache_array_address(isolate); |
3803 __ ldr(cache_entry, MemOperand(cache_entry, type_ * sizeof( | 3806 __ mov(cache_entry, Operand(cache_array)); |
3804 Isolate::Current()->transcendental_cache()->caches_[0]))); | 3807 // cache_entry points to cache array. |
| 3808 int cache_array_index |
| 3809 = type_ * sizeof(isolate->transcendental_cache()->caches_[0]); |
| 3810 __ ldr(cache_entry, MemOperand(cache_entry, cache_array_index)); |
3805 // r0 points to the cache for the type type_. | 3811 // r0 points to the cache for the type type_. |
3806 // If NULL, the cache hasn't been initialized yet, so go through runtime. | 3812 // If NULL, the cache hasn't been initialized yet, so go through runtime. |
3807 __ cmp(cache_entry, Operand(0, RelocInfo::NONE)); | 3813 __ cmp(cache_entry, Operand(0, RelocInfo::NONE)); |
3808 __ b(eq, &invalid_cache); | 3814 __ b(eq, &invalid_cache); |
3809 | 3815 |
3810 #ifdef DEBUG | 3816 #ifdef DEBUG |
3811 // Check that the layout of cache elements match expectations. | 3817 // Check that the layout of cache elements match expectations. |
3812 { TranscendentalCache::SubCache::Element test_elem[2]; | 3818 { TranscendentalCache::SubCache::Element test_elem[2]; |
3813 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); | 3819 char* elem_start = reinterpret_cast<char*>(&test_elem[0]); |
3814 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); | 3820 char* elem2_start = reinterpret_cast<char*>(&test_elem[1]); |
(...skipping 24 matching lines...) Expand all Loading... |
3839 } else { | 3845 } else { |
3840 // Load result into d2. | 3846 // Load result into d2. |
3841 __ vldr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset)); | 3847 __ vldr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset)); |
3842 } | 3848 } |
3843 __ Ret(); | 3849 __ Ret(); |
3844 } // if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) | 3850 } // if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) |
3845 | 3851 |
3846 __ bind(&calculate); | 3852 __ bind(&calculate); |
3847 if (tagged) { | 3853 if (tagged) { |
3848 __ bind(&invalid_cache); | 3854 __ bind(&invalid_cache); |
3849 __ TailCallExternalReference(ExternalReference(RuntimeFunction()), 1, 1); | 3855 ExternalReference runtime_function = |
| 3856 ExternalReference(RuntimeFunction(), masm->isolate()); |
| 3857 __ TailCallExternalReference(runtime_function, 1, 1); |
3850 } else { | 3858 } else { |
3851 if (!Isolate::Current()->cpu_features()->IsSupported(VFP3)) UNREACHABLE(); | 3859 if (!Isolate::Current()->cpu_features()->IsSupported(VFP3)) UNREACHABLE(); |
3852 CpuFeatures::Scope scope(VFP3); | 3860 CpuFeatures::Scope scope(VFP3); |
3853 | 3861 |
3854 Label no_update; | 3862 Label no_update; |
3855 Label skip_cache; | 3863 Label skip_cache; |
3856 const Register heap_number_map = r5; | 3864 const Register heap_number_map = r5; |
3857 | 3865 |
3858 // Call C function to calculate the result and update the cache. | 3866 // Call C function to calculate the result and update the cache. |
3859 // Register r0 holds precalculated cache entry address; preserve | 3867 // Register r0 holds precalculated cache entry address; preserve |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3902 __ push(scratch0); | 3910 __ push(scratch0); |
3903 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); | 3911 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); |
3904 __ LeaveInternalFrame(); | 3912 __ LeaveInternalFrame(); |
3905 __ Ret(); | 3913 __ Ret(); |
3906 } | 3914 } |
3907 } | 3915 } |
3908 | 3916 |
3909 | 3917 |
3910 void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm, | 3918 void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm, |
3911 Register scratch) { | 3919 Register scratch) { |
| 3920 Isolate* isolate = masm->isolate(); |
| 3921 |
3912 __ push(lr); | 3922 __ push(lr); |
3913 __ PrepareCallCFunction(2, scratch); | 3923 __ PrepareCallCFunction(2, scratch); |
3914 __ vmov(r0, r1, d2); | 3924 __ vmov(r0, r1, d2); |
3915 switch (type_) { | 3925 switch (type_) { |
3916 case TranscendentalCache::SIN: | 3926 case TranscendentalCache::SIN: |
3917 __ CallCFunction(ExternalReference::math_sin_double_function(), 2); | 3927 __ CallCFunction(ExternalReference::math_sin_double_function(isolate), 2); |
3918 break; | 3928 break; |
3919 case TranscendentalCache::COS: | 3929 case TranscendentalCache::COS: |
3920 __ CallCFunction(ExternalReference::math_cos_double_function(), 2); | 3930 __ CallCFunction(ExternalReference::math_cos_double_function(isolate), 2); |
3921 break; | 3931 break; |
3922 case TranscendentalCache::LOG: | 3932 case TranscendentalCache::LOG: |
3923 __ CallCFunction(ExternalReference::math_log_double_function(), 2); | 3933 __ CallCFunction(ExternalReference::math_log_double_function(isolate), 2); |
3924 break; | 3934 break; |
3925 default: | 3935 default: |
3926 UNIMPLEMENTED(); | 3936 UNIMPLEMENTED(); |
3927 break; | 3937 break; |
3928 } | 3938 } |
3929 __ pop(lr); | 3939 __ pop(lr); |
3930 } | 3940 } |
3931 | 3941 |
3932 | 3942 |
3933 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { | 3943 Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4133 // the heap number is callee-saved. | 4143 // the heap number is callee-saved. |
4134 __ AllocateHeapNumber(heapnumber, | 4144 __ AllocateHeapNumber(heapnumber, |
4135 scratch, | 4145 scratch, |
4136 scratch2, | 4146 scratch2, |
4137 heapnumbermap, | 4147 heapnumbermap, |
4138 &call_runtime); | 4148 &call_runtime); |
4139 __ push(lr); | 4149 __ push(lr); |
4140 __ PrepareCallCFunction(3, scratch); | 4150 __ PrepareCallCFunction(3, scratch); |
4141 __ mov(r2, exponent); | 4151 __ mov(r2, exponent); |
4142 __ vmov(r0, r1, double_base); | 4152 __ vmov(r0, r1, double_base); |
4143 __ CallCFunction(ExternalReference::power_double_int_function(), 3); | 4153 __ CallCFunction( |
| 4154 ExternalReference::power_double_int_function(masm->isolate()), 3); |
4144 __ pop(lr); | 4155 __ pop(lr); |
4145 __ GetCFunctionDoubleResult(double_result); | 4156 __ GetCFunctionDoubleResult(double_result); |
4146 __ vstr(double_result, | 4157 __ vstr(double_result, |
4147 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); | 4158 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); |
4148 __ mov(r0, heapnumber); | 4159 __ mov(r0, heapnumber); |
4149 __ Ret(2 * kPointerSize); | 4160 __ Ret(2 * kPointerSize); |
4150 | 4161 |
4151 __ bind(&exponent_not_smi); | 4162 __ bind(&exponent_not_smi); |
4152 __ ldr(scratch, FieldMemOperand(exponent, JSObject::kMapOffset)); | 4163 __ ldr(scratch, FieldMemOperand(exponent, JSObject::kMapOffset)); |
4153 __ cmp(scratch, heapnumbermap); | 4164 __ cmp(scratch, heapnumbermap); |
4154 __ b(ne, &call_runtime); | 4165 __ b(ne, &call_runtime); |
4155 // Exponent is a heapnumber. Load it into double register. | 4166 // Exponent is a heapnumber. Load it into double register. |
4156 __ vldr(double_exponent, | 4167 __ vldr(double_exponent, |
4157 FieldMemOperand(exponent, HeapNumber::kValueOffset)); | 4168 FieldMemOperand(exponent, HeapNumber::kValueOffset)); |
4158 | 4169 |
4159 // The base and the exponent are in double registers. | 4170 // The base and the exponent are in double registers. |
4160 // Allocate a heap number and call a C function for | 4171 // Allocate a heap number and call a C function for |
4161 // double exponents. The register containing | 4172 // double exponents. The register containing |
4162 // the heap number is callee-saved. | 4173 // the heap number is callee-saved. |
4163 __ AllocateHeapNumber(heapnumber, | 4174 __ AllocateHeapNumber(heapnumber, |
4164 scratch, | 4175 scratch, |
4165 scratch2, | 4176 scratch2, |
4166 heapnumbermap, | 4177 heapnumbermap, |
4167 &call_runtime); | 4178 &call_runtime); |
4168 __ push(lr); | 4179 __ push(lr); |
4169 __ PrepareCallCFunction(4, scratch); | 4180 __ PrepareCallCFunction(4, scratch); |
4170 __ vmov(r0, r1, double_base); | 4181 __ vmov(r0, r1, double_base); |
4171 __ vmov(r2, r3, double_exponent); | 4182 __ vmov(r2, r3, double_exponent); |
4172 __ CallCFunction(ExternalReference::power_double_double_function(), 4); | 4183 __ CallCFunction( |
| 4184 ExternalReference::power_double_double_function(masm->isolate()), 4); |
4173 __ pop(lr); | 4185 __ pop(lr); |
4174 __ GetCFunctionDoubleResult(double_result); | 4186 __ GetCFunctionDoubleResult(double_result); |
4175 __ vstr(double_result, | 4187 __ vstr(double_result, |
4176 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); | 4188 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); |
4177 __ mov(r0, heapnumber); | 4189 __ mov(r0, heapnumber); |
4178 __ Ret(2 * kPointerSize); | 4190 __ Ret(2 * kPointerSize); |
4179 } | 4191 } |
4180 | 4192 |
4181 __ bind(&call_runtime); | 4193 __ bind(&call_runtime); |
4182 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); | 4194 __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1); |
(...skipping 19 matching lines...) Expand all Loading... |
4202 void CEntryStub::GenerateCore(MacroAssembler* masm, | 4214 void CEntryStub::GenerateCore(MacroAssembler* masm, |
4203 Label* throw_normal_exception, | 4215 Label* throw_normal_exception, |
4204 Label* throw_termination_exception, | 4216 Label* throw_termination_exception, |
4205 Label* throw_out_of_memory_exception, | 4217 Label* throw_out_of_memory_exception, |
4206 bool do_gc, | 4218 bool do_gc, |
4207 bool always_allocate) { | 4219 bool always_allocate) { |
4208 // r0: result parameter for PerformGC, if any | 4220 // r0: result parameter for PerformGC, if any |
4209 // r4: number of arguments including receiver (C callee-saved) | 4221 // r4: number of arguments including receiver (C callee-saved) |
4210 // r5: pointer to builtin function (C callee-saved) | 4222 // r5: pointer to builtin function (C callee-saved) |
4211 // r6: pointer to the first argument (C callee-saved) | 4223 // r6: pointer to the first argument (C callee-saved) |
| 4224 Isolate* isolate = masm->isolate(); |
4212 | 4225 |
4213 if (do_gc) { | 4226 if (do_gc) { |
4214 // Passing r0. | 4227 // Passing r0. |
4215 __ PrepareCallCFunction(1, r1); | 4228 __ PrepareCallCFunction(1, r1); |
4216 __ CallCFunction(ExternalReference::perform_gc_function(), 1); | 4229 __ CallCFunction(ExternalReference::perform_gc_function(isolate), 1); |
4217 } | 4230 } |
4218 | 4231 |
4219 ExternalReference scope_depth = | 4232 ExternalReference scope_depth = |
4220 ExternalReference::heap_always_allocate_scope_depth(); | 4233 ExternalReference::heap_always_allocate_scope_depth(isolate); |
4221 if (always_allocate) { | 4234 if (always_allocate) { |
4222 __ mov(r0, Operand(scope_depth)); | 4235 __ mov(r0, Operand(scope_depth)); |
4223 __ ldr(r1, MemOperand(r0)); | 4236 __ ldr(r1, MemOperand(r0)); |
4224 __ add(r1, r1, Operand(1)); | 4237 __ add(r1, r1, Operand(1)); |
4225 __ str(r1, MemOperand(r0)); | 4238 __ str(r1, MemOperand(r0)); |
4226 } | 4239 } |
4227 | 4240 |
4228 // Call C built-in. | 4241 // Call C built-in. |
4229 // r0 = argc, r1 = argv | 4242 // r0 = argc, r1 = argv |
4230 __ mov(r0, Operand(r4)); | 4243 __ mov(r0, Operand(r4)); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4295 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0); | 4308 STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0); |
4296 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); | 4309 __ tst(r0, Operand(((1 << kFailureTypeTagSize) - 1) << kFailureTagSize)); |
4297 __ b(eq, &retry); | 4310 __ b(eq, &retry); |
4298 | 4311 |
4299 // Special handling of out of memory exceptions. | 4312 // Special handling of out of memory exceptions. |
4300 Failure* out_of_memory = Failure::OutOfMemoryException(); | 4313 Failure* out_of_memory = Failure::OutOfMemoryException(); |
4301 __ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); | 4314 __ cmp(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); |
4302 __ b(eq, throw_out_of_memory_exception); | 4315 __ b(eq, throw_out_of_memory_exception); |
4303 | 4316 |
4304 // Retrieve the pending exception and clear the variable. | 4317 // Retrieve the pending exception and clear the variable. |
4305 __ mov(ip, Operand(ExternalReference::the_hole_value_location())); | 4318 __ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate))); |
4306 __ ldr(r3, MemOperand(ip)); | 4319 __ ldr(r3, MemOperand(ip)); |
4307 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address))); | 4320 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 4321 isolate))); |
4308 __ ldr(r0, MemOperand(ip)); | 4322 __ ldr(r0, MemOperand(ip)); |
4309 __ str(r3, MemOperand(ip)); | 4323 __ str(r3, MemOperand(ip)); |
4310 | 4324 |
4311 // Special handling of termination exceptions which are uncatchable | 4325 // Special handling of termination exceptions which are uncatchable |
4312 // by javascript code. | 4326 // by javascript code. |
4313 __ cmp(r0, Operand(FACTORY->termination_exception())); | 4327 __ cmp(r0, Operand(isolate->factory()->termination_exception())); |
4314 __ b(eq, throw_termination_exception); | 4328 __ b(eq, throw_termination_exception); |
4315 | 4329 |
4316 // Handle normal exception. | 4330 // Handle normal exception. |
4317 __ jmp(throw_normal_exception); | 4331 __ jmp(throw_normal_exception); |
4318 | 4332 |
4319 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying | 4333 __ bind(&retry); // pass last failure (r0) as parameter (r0) when retrying |
4320 } | 4334 } |
4321 | 4335 |
4322 | 4336 |
4323 void CEntryStub::Generate(MacroAssembler* masm) { | 4337 void CEntryStub::Generate(MacroAssembler* masm) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4411 // r2: receiver | 4425 // r2: receiver |
4412 // r3: argc | 4426 // r3: argc |
4413 __ ldr(r4, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize)); // argv | 4427 __ ldr(r4, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize)); // argv |
4414 | 4428 |
4415 // Push a frame with special values setup to mark it as an entry frame. | 4429 // Push a frame with special values setup to mark it as an entry frame. |
4416 // r0: code entry | 4430 // r0: code entry |
4417 // r1: function | 4431 // r1: function |
4418 // r2: receiver | 4432 // r2: receiver |
4419 // r3: argc | 4433 // r3: argc |
4420 // r4: argv | 4434 // r4: argv |
| 4435 Isolate* isolate = masm->isolate(); |
4421 __ mov(r8, Operand(-1)); // Push a bad frame pointer to fail if it is used. | 4436 __ mov(r8, Operand(-1)); // Push a bad frame pointer to fail if it is used. |
4422 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; | 4437 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; |
4423 __ mov(r7, Operand(Smi::FromInt(marker))); | 4438 __ mov(r7, Operand(Smi::FromInt(marker))); |
4424 __ mov(r6, Operand(Smi::FromInt(marker))); | 4439 __ mov(r6, Operand(Smi::FromInt(marker))); |
4425 __ mov(r5, Operand(ExternalReference(Isolate::k_c_entry_fp_address))); | 4440 __ mov(r5, |
| 4441 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); |
4426 __ ldr(r5, MemOperand(r5)); | 4442 __ ldr(r5, MemOperand(r5)); |
4427 __ Push(r8, r7, r6, r5); | 4443 __ Push(r8, r7, r6, r5); |
4428 | 4444 |
4429 // Setup frame pointer for the frame to be pushed. | 4445 // Setup frame pointer for the frame to be pushed. |
4430 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); | 4446 __ add(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); |
4431 | 4447 |
4432 #ifdef ENABLE_LOGGING_AND_PROFILING | 4448 #ifdef ENABLE_LOGGING_AND_PROFILING |
4433 // If this is the outermost JS call, set js_entry_sp value. | 4449 // If this is the outermost JS call, set js_entry_sp value. |
4434 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address); | 4450 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); |
4435 __ mov(r5, Operand(ExternalReference(js_entry_sp))); | 4451 __ mov(r5, Operand(ExternalReference(js_entry_sp))); |
4436 __ ldr(r6, MemOperand(r5)); | 4452 __ ldr(r6, MemOperand(r5)); |
4437 __ cmp(r6, Operand(0, RelocInfo::NONE)); | 4453 __ cmp(r6, Operand(0, RelocInfo::NONE)); |
4438 __ str(fp, MemOperand(r5), eq); | 4454 __ str(fp, MemOperand(r5), eq); |
4439 #endif | 4455 #endif |
4440 | 4456 |
4441 // Call a faked try-block that does the invoke. | 4457 // Call a faked try-block that does the invoke. |
4442 __ bl(&invoke); | 4458 __ bl(&invoke); |
4443 | 4459 |
4444 // Caught exception: Store result (exception) in the pending | 4460 // Caught exception: Store result (exception) in the pending |
4445 // exception field in the JSEnv and return a failure sentinel. | 4461 // exception field in the JSEnv and return a failure sentinel. |
4446 // Coming in here the fp will be invalid because the PushTryHandler below | 4462 // Coming in here the fp will be invalid because the PushTryHandler below |
4447 // sets it to 0 to signal the existence of the JSEntry frame. | 4463 // sets it to 0 to signal the existence of the JSEntry frame. |
4448 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address))); | 4464 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 4465 isolate))); |
4449 __ str(r0, MemOperand(ip)); | 4466 __ str(r0, MemOperand(ip)); |
4450 __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); | 4467 __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); |
4451 __ b(&exit); | 4468 __ b(&exit); |
4452 | 4469 |
4453 // Invoke: Link this frame into the handler chain. | 4470 // Invoke: Link this frame into the handler chain. |
4454 __ bind(&invoke); | 4471 __ bind(&invoke); |
4455 // Must preserve r0-r4, r5-r7 are available. | 4472 // Must preserve r0-r4, r5-r7 are available. |
4456 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); | 4473 __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER); |
4457 // If an exception not caught by another handler occurs, this handler | 4474 // If an exception not caught by another handler occurs, this handler |
4458 // returns control to the code after the bl(&invoke) above, which | 4475 // returns control to the code after the bl(&invoke) above, which |
4459 // restores all kCalleeSaved registers (including cp and fp) to their | 4476 // restores all kCalleeSaved registers (including cp and fp) to their |
4460 // saved values before returning a failure to C. | 4477 // saved values before returning a failure to C. |
4461 | 4478 |
4462 // Clear any pending exceptions. | 4479 // Clear any pending exceptions. |
4463 __ mov(ip, Operand(ExternalReference::the_hole_value_location())); | 4480 __ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate))); |
4464 __ ldr(r5, MemOperand(ip)); | 4481 __ ldr(r5, MemOperand(ip)); |
4465 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address))); | 4482 __ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 4483 isolate))); |
4466 __ str(r5, MemOperand(ip)); | 4484 __ str(r5, MemOperand(ip)); |
4467 | 4485 |
4468 // Invoke the function by calling through JS entry trampoline builtin. | 4486 // Invoke the function by calling through JS entry trampoline builtin. |
4469 // Notice that we cannot store a reference to the trampoline code directly in | 4487 // Notice that we cannot store a reference to the trampoline code directly in |
4470 // this stub, because runtime stubs are not traversed when doing GC. | 4488 // this stub, because runtime stubs are not traversed when doing GC. |
4471 | 4489 |
4472 // Expected registers by Builtins::JSEntryTrampoline | 4490 // Expected registers by Builtins::JSEntryTrampoline |
4473 // r0: code entry | 4491 // r0: code entry |
4474 // r1: function | 4492 // r1: function |
4475 // r2: receiver | 4493 // r2: receiver |
4476 // r3: argc | 4494 // r3: argc |
4477 // r4: argv | 4495 // r4: argv |
4478 if (is_construct) { | 4496 if (is_construct) { |
4479 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline); | 4497 ExternalReference construct_entry(Builtins::JSConstructEntryTrampoline, |
| 4498 isolate); |
4480 __ mov(ip, Operand(construct_entry)); | 4499 __ mov(ip, Operand(construct_entry)); |
4481 } else { | 4500 } else { |
4482 ExternalReference entry(Builtins::JSEntryTrampoline); | 4501 ExternalReference entry(Builtins::JSEntryTrampoline, isolate); |
4483 __ mov(ip, Operand(entry)); | 4502 __ mov(ip, Operand(entry)); |
4484 } | 4503 } |
4485 __ ldr(ip, MemOperand(ip)); // deref address | 4504 __ ldr(ip, MemOperand(ip)); // deref address |
4486 | 4505 |
4487 // Branch and link to JSEntryTrampoline. We don't use the double underscore | 4506 // Branch and link to JSEntryTrampoline. We don't use the double underscore |
4488 // macro for the add instruction because we don't want the coverage tool | 4507 // macro for the add instruction because we don't want the coverage tool |
4489 // inserting instructions here after we read the pc. | 4508 // inserting instructions here after we read the pc. |
4490 __ mov(lr, Operand(pc)); | 4509 __ mov(lr, Operand(pc)); |
4491 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); | 4510 masm->add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
4492 | 4511 |
4493 // Unlink this frame from the handler chain. When reading the | 4512 // Unlink this frame from the handler chain. When reading the |
4494 // address of the next handler, there is no need to use the address | 4513 // address of the next handler, there is no need to use the address |
4495 // displacement since the current stack pointer (sp) points directly | 4514 // displacement since the current stack pointer (sp) points directly |
4496 // to the stack handler. | 4515 // to the stack handler. |
4497 __ ldr(r3, MemOperand(sp, StackHandlerConstants::kNextOffset)); | 4516 __ ldr(r3, MemOperand(sp, StackHandlerConstants::kNextOffset)); |
4498 __ mov(ip, Operand(ExternalReference(Isolate::k_handler_address))); | 4517 __ mov(ip, Operand(ExternalReference(Isolate::k_handler_address, isolate))); |
4499 __ str(r3, MemOperand(ip)); | 4518 __ str(r3, MemOperand(ip)); |
4500 // No need to restore registers | 4519 // No need to restore registers |
4501 __ add(sp, sp, Operand(StackHandlerConstants::kSize)); | 4520 __ add(sp, sp, Operand(StackHandlerConstants::kSize)); |
4502 | 4521 |
4503 #ifdef ENABLE_LOGGING_AND_PROFILING | 4522 #ifdef ENABLE_LOGGING_AND_PROFILING |
4504 // If current FP value is the same as js_entry_sp value, it means that | 4523 // If current FP value is the same as js_entry_sp value, it means that |
4505 // the current function is the outermost. | 4524 // the current function is the outermost. |
4506 __ mov(r5, Operand(ExternalReference(js_entry_sp))); | 4525 __ mov(r5, Operand(ExternalReference(js_entry_sp))); |
4507 __ ldr(r6, MemOperand(r5)); | 4526 __ ldr(r6, MemOperand(r5)); |
4508 __ cmp(fp, Operand(r6)); | 4527 __ cmp(fp, Operand(r6)); |
4509 __ mov(r6, Operand(0, RelocInfo::NONE), LeaveCC, eq); | 4528 __ mov(r6, Operand(0, RelocInfo::NONE), LeaveCC, eq); |
4510 __ str(r6, MemOperand(r5), eq); | 4529 __ str(r6, MemOperand(r5), eq); |
4511 #endif | 4530 #endif |
4512 | 4531 |
4513 __ bind(&exit); // r0 holds result | 4532 __ bind(&exit); // r0 holds result |
4514 // Restore the top frame descriptors from the stack. | 4533 // Restore the top frame descriptors from the stack. |
4515 __ pop(r3); | 4534 __ pop(r3); |
4516 __ mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address))); | 4535 __ mov(ip, |
| 4536 Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); |
4517 __ str(r3, MemOperand(ip)); | 4537 __ str(r3, MemOperand(ip)); |
4518 | 4538 |
4519 // Reset the stack to the callee saved registers. | 4539 // Reset the stack to the callee saved registers. |
4520 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); | 4540 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); |
4521 | 4541 |
4522 // Restore callee-saved registers and return. | 4542 // Restore callee-saved registers and return. |
4523 #ifdef DEBUG | 4543 #ifdef DEBUG |
4524 if (FLAG_debug_code) { | 4544 if (FLAG_debug_code) { |
4525 __ mov(lr, Operand(pc)); | 4545 __ mov(lr, Operand(pc)); |
4526 } | 4546 } |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4902 // Allocation of registers for this function. These are in callee save | 4922 // Allocation of registers for this function. These are in callee save |
4903 // registers and will be preserved by the call to the native RegExp code, as | 4923 // registers and will be preserved by the call to the native RegExp code, as |
4904 // this code is called using the normal C calling convention. When calling | 4924 // this code is called using the normal C calling convention. When calling |
4905 // directly from generated code the native RegExp code will not do a GC and | 4925 // directly from generated code the native RegExp code will not do a GC and |
4906 // therefore the content of these registers are safe to use after the call. | 4926 // therefore the content of these registers are safe to use after the call. |
4907 Register subject = r4; | 4927 Register subject = r4; |
4908 Register regexp_data = r5; | 4928 Register regexp_data = r5; |
4909 Register last_match_info_elements = r6; | 4929 Register last_match_info_elements = r6; |
4910 | 4930 |
4911 // Ensure that a RegExp stack is allocated. | 4931 // Ensure that a RegExp stack is allocated. |
| 4932 Isolate* isolate = masm->isolate(); |
4912 ExternalReference address_of_regexp_stack_memory_address = | 4933 ExternalReference address_of_regexp_stack_memory_address = |
4913 ExternalReference::address_of_regexp_stack_memory_address(); | 4934 ExternalReference::address_of_regexp_stack_memory_address(isolate); |
4914 ExternalReference address_of_regexp_stack_memory_size = | 4935 ExternalReference address_of_regexp_stack_memory_size = |
4915 ExternalReference::address_of_regexp_stack_memory_size(); | 4936 ExternalReference::address_of_regexp_stack_memory_size(isolate); |
4916 __ mov(r0, Operand(address_of_regexp_stack_memory_size)); | 4937 __ mov(r0, Operand(address_of_regexp_stack_memory_size)); |
4917 __ ldr(r0, MemOperand(r0, 0)); | 4938 __ ldr(r0, MemOperand(r0, 0)); |
4918 __ tst(r0, Operand(r0)); | 4939 __ tst(r0, Operand(r0)); |
4919 __ b(eq, &runtime); | 4940 __ b(eq, &runtime); |
4920 | 4941 |
4921 // Check that the first argument is a JSRegExp object. | 4942 // Check that the first argument is a JSRegExp object. |
4922 __ ldr(r0, MemOperand(sp, kJSRegExpOffset)); | 4943 __ ldr(r0, MemOperand(sp, kJSRegExpOffset)); |
4923 STATIC_ASSERT(kSmiTag == 0); | 4944 STATIC_ASSERT(kSmiTag == 0); |
4924 __ tst(r0, Operand(kSmiTagMask)); | 4945 __ tst(r0, Operand(kSmiTagMask)); |
4925 __ b(eq, &runtime); | 4946 __ b(eq, &runtime); |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5088 | 5109 |
5089 // Argument 6 (sp[8]): Start (high end) of backtracking stack memory area. | 5110 // Argument 6 (sp[8]): Start (high end) of backtracking stack memory area. |
5090 __ mov(r0, Operand(address_of_regexp_stack_memory_address)); | 5111 __ mov(r0, Operand(address_of_regexp_stack_memory_address)); |
5091 __ ldr(r0, MemOperand(r0, 0)); | 5112 __ ldr(r0, MemOperand(r0, 0)); |
5092 __ mov(r2, Operand(address_of_regexp_stack_memory_size)); | 5113 __ mov(r2, Operand(address_of_regexp_stack_memory_size)); |
5093 __ ldr(r2, MemOperand(r2, 0)); | 5114 __ ldr(r2, MemOperand(r2, 0)); |
5094 __ add(r0, r0, Operand(r2)); | 5115 __ add(r0, r0, Operand(r2)); |
5095 __ str(r0, MemOperand(sp, 2 * kPointerSize)); | 5116 __ str(r0, MemOperand(sp, 2 * kPointerSize)); |
5096 | 5117 |
5097 // Argument 5 (sp[4]): static offsets vector buffer. | 5118 // Argument 5 (sp[4]): static offsets vector buffer. |
5098 __ mov(r0, Operand(ExternalReference::address_of_static_offsets_vector())); | 5119 __ mov(r0, |
| 5120 Operand(ExternalReference::address_of_static_offsets_vector(isolate))); |
5099 __ str(r0, MemOperand(sp, 1 * kPointerSize)); | 5121 __ str(r0, MemOperand(sp, 1 * kPointerSize)); |
5100 | 5122 |
5101 // For arguments 4 and 3 get string length, calculate start of string data and | 5123 // For arguments 4 and 3 get string length, calculate start of string data and |
5102 // calculate the shift of the index (0 for ASCII and 1 for two byte). | 5124 // calculate the shift of the index (0 for ASCII and 1 for two byte). |
5103 __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset)); | 5125 __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset)); |
5104 __ mov(r0, Operand(r0, ASR, kSmiTagSize)); | 5126 __ mov(r0, Operand(r0, ASR, kSmiTagSize)); |
5105 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); | 5127 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); |
5106 __ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 5128 __ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
5107 __ eor(r3, r3, Operand(1)); | 5129 __ eor(r3, r3, Operand(1)); |
5108 // Argument 4 (r3): End of string data | 5130 // Argument 4 (r3): End of string data |
(...skipping 27 matching lines...) Expand all Loading... |
5136 Label failure; | 5158 Label failure; |
5137 __ cmp(r0, Operand(NativeRegExpMacroAssembler::FAILURE)); | 5159 __ cmp(r0, Operand(NativeRegExpMacroAssembler::FAILURE)); |
5138 __ b(eq, &failure); | 5160 __ b(eq, &failure); |
5139 __ cmp(r0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); | 5161 __ cmp(r0, Operand(NativeRegExpMacroAssembler::EXCEPTION)); |
5140 // If not exception it can only be retry. Handle that in the runtime system. | 5162 // If not exception it can only be retry. Handle that in the runtime system. |
5141 __ b(ne, &runtime); | 5163 __ b(ne, &runtime); |
5142 // Result must now be exception. If there is no pending exception already a | 5164 // Result must now be exception. If there is no pending exception already a |
5143 // stack overflow (on the backtrack stack) was detected in RegExp code but | 5165 // stack overflow (on the backtrack stack) was detected in RegExp code but |
5144 // haven't created the exception yet. Handle that in the runtime system. | 5166 // haven't created the exception yet. Handle that in the runtime system. |
5145 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 5167 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
5146 __ mov(r1, Operand(ExternalReference::the_hole_value_location())); | 5168 __ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate))); |
5147 __ ldr(r1, MemOperand(r1, 0)); | 5169 __ ldr(r1, MemOperand(r1, 0)); |
5148 __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address))); | 5170 __ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, |
| 5171 isolate))); |
5149 __ ldr(r0, MemOperand(r2, 0)); | 5172 __ ldr(r0, MemOperand(r2, 0)); |
5150 __ cmp(r0, r1); | 5173 __ cmp(r0, r1); |
5151 __ b(eq, &runtime); | 5174 __ b(eq, &runtime); |
5152 | 5175 |
5153 __ str(r1, MemOperand(r2, 0)); // Clear pending exception. | 5176 __ str(r1, MemOperand(r2, 0)); // Clear pending exception. |
5154 | 5177 |
5155 // Check if the exception is a termination. If so, throw as uncatchable. | 5178 // Check if the exception is a termination. If so, throw as uncatchable. |
5156 __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex); | 5179 __ LoadRoot(ip, Heap::kTerminationExceptionRootIndex); |
5157 __ cmp(r0, ip); | 5180 __ cmp(r0, ip); |
5158 Label termination_exception; | 5181 Label termination_exception; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5191 RegExpImpl::kLastSubjectOffset)); | 5214 RegExpImpl::kLastSubjectOffset)); |
5192 __ RecordWrite(r3, Operand(RegExpImpl::kLastSubjectOffset), r2, r7); | 5215 __ RecordWrite(r3, Operand(RegExpImpl::kLastSubjectOffset), r2, r7); |
5193 __ str(subject, | 5216 __ str(subject, |
5194 FieldMemOperand(last_match_info_elements, | 5217 FieldMemOperand(last_match_info_elements, |
5195 RegExpImpl::kLastInputOffset)); | 5218 RegExpImpl::kLastInputOffset)); |
5196 __ mov(r3, last_match_info_elements); | 5219 __ mov(r3, last_match_info_elements); |
5197 __ RecordWrite(r3, Operand(RegExpImpl::kLastInputOffset), r2, r7); | 5220 __ RecordWrite(r3, Operand(RegExpImpl::kLastInputOffset), r2, r7); |
5198 | 5221 |
5199 // Get the static offsets vector filled by the native regexp code. | 5222 // Get the static offsets vector filled by the native regexp code. |
5200 ExternalReference address_of_static_offsets_vector = | 5223 ExternalReference address_of_static_offsets_vector = |
5201 ExternalReference::address_of_static_offsets_vector(); | 5224 ExternalReference::address_of_static_offsets_vector(isolate); |
5202 __ mov(r2, Operand(address_of_static_offsets_vector)); | 5225 __ mov(r2, Operand(address_of_static_offsets_vector)); |
5203 | 5226 |
5204 // r1: number of capture registers | 5227 // r1: number of capture registers |
5205 // r2: offsets vector | 5228 // r2: offsets vector |
5206 Label next_capture, done; | 5229 Label next_capture, done; |
5207 // Capture register counter starts from number of capture registers and | 5230 // Capture register counter starts from number of capture registers and |
5208 // counts down until wraping after zero. | 5231 // counts down until wraping after zero. |
5209 __ add(r0, | 5232 __ add(r0, |
5210 last_match_info_elements, | 5233 last_match_info_elements, |
5211 Operand(RegExpImpl::kFirstCaptureOffset - kHeapObjectTag)); | 5234 Operand(RegExpImpl::kFirstCaptureOffset - kHeapObjectTag)); |
(...skipping 1574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6786 __ bind(&miss); | 6809 __ bind(&miss); |
6787 GenerateMiss(masm); | 6810 GenerateMiss(masm); |
6788 } | 6811 } |
6789 | 6812 |
6790 | 6813 |
6791 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 6814 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
6792 __ Push(r1, r0); | 6815 __ Push(r1, r0); |
6793 __ push(lr); | 6816 __ push(lr); |
6794 | 6817 |
6795 // Call the runtime system in a fresh internal frame. | 6818 // Call the runtime system in a fresh internal frame. |
6796 ExternalReference miss = ExternalReference(IC_Utility(IC::kCompareIC_Miss)); | 6819 ExternalReference miss = |
| 6820 ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate()); |
6797 __ EnterInternalFrame(); | 6821 __ EnterInternalFrame(); |
6798 __ Push(r1, r0); | 6822 __ Push(r1, r0); |
6799 __ mov(ip, Operand(Smi::FromInt(op_))); | 6823 __ mov(ip, Operand(Smi::FromInt(op_))); |
6800 __ push(ip); | 6824 __ push(ip); |
6801 __ CallExternalReference(miss, 3); | 6825 __ CallExternalReference(miss, 3); |
6802 __ LeaveInternalFrame(); | 6826 __ LeaveInternalFrame(); |
6803 // Compute the entry point of the rewritten stub. | 6827 // Compute the entry point of the rewritten stub. |
6804 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 6828 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
6805 // Restore registers. | 6829 // Restore registers. |
6806 __ pop(lr); | 6830 __ pop(lr); |
(...skipping 27 matching lines...) Expand all Loading... |
6834 __ str(pc, MemOperand(sp, 0)); | 6858 __ str(pc, MemOperand(sp, 0)); |
6835 __ Jump(target); // Call the C++ function. | 6859 __ Jump(target); // Call the C++ function. |
6836 } | 6860 } |
6837 | 6861 |
6838 | 6862 |
6839 #undef __ | 6863 #undef __ |
6840 | 6864 |
6841 } } // namespace v8::internal | 6865 } } // namespace v8::internal |
6842 | 6866 |
6843 #endif // V8_TARGET_ARCH_ARM | 6867 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |