OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/base/utils/random-number-generator.h" | 9 #include "src/base/utils/random-number-generator.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
11 #include "src/codegen.h" | 11 #include "src/codegen.h" |
12 #include "src/third_party/fdlibm/fdlibm.h" | 12 #include "src/third_party/fdlibm/fdlibm.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 | 16 |
17 #define RUNTIME_UNARY_MATH(Name, name) \ | 17 #define RUNTIME_UNARY_MATH(Name, name) \ |
18 RUNTIME_FUNCTION(Runtime_Math##Name) { \ | 18 RUNTIME_FUNCTION(Runtime_Math##Name) { \ |
19 HandleScope scope(isolate); \ | 19 HandleScope scope(isolate); \ |
20 DCHECK(args.length() == 1); \ | 20 DCHECK(args.length() == 1); \ |
21 isolate->counters()->math_##name()->Increment(); \ | 21 isolate->counters()->math_##name##_runtime()->Increment(); \ |
22 CONVERT_DOUBLE_ARG_CHECKED(x, 0); \ | 22 CONVERT_DOUBLE_ARG_CHECKED(x, 0); \ |
23 return *isolate->factory()->NewHeapNumber(std::name(x)); \ | 23 return *isolate->factory()->NewHeapNumber(std::name(x)); \ |
24 } | 24 } |
25 | 25 |
26 RUNTIME_UNARY_MATH(Acos, acos) | 26 RUNTIME_UNARY_MATH(Acos, acos) |
27 RUNTIME_UNARY_MATH(Asin, asin) | 27 RUNTIME_UNARY_MATH(Asin, asin) |
28 RUNTIME_UNARY_MATH(Atan, atan) | 28 RUNTIME_UNARY_MATH(Atan, atan) |
29 RUNTIME_UNARY_MATH(LogRT, log) | 29 RUNTIME_UNARY_MATH(LogRT, log) |
30 #undef RUNTIME_UNARY_MATH | 30 #undef RUNTIME_UNARY_MATH |
31 | 31 |
32 | 32 |
33 RUNTIME_FUNCTION(Runtime_DoubleHi) { | 33 RUNTIME_FUNCTION(Runtime_DoubleHi) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 return Smi::FromInt(fdlibm::rempio2(x, y)); | 74 return Smi::FromInt(fdlibm::rempio2(x, y)); |
75 } | 75 } |
76 | 76 |
77 | 77 |
78 static const double kPiDividedBy4 = 0.78539816339744830962; | 78 static const double kPiDividedBy4 = 0.78539816339744830962; |
79 | 79 |
80 | 80 |
81 RUNTIME_FUNCTION(Runtime_MathAtan2) { | 81 RUNTIME_FUNCTION(Runtime_MathAtan2) { |
82 HandleScope scope(isolate); | 82 HandleScope scope(isolate); |
83 DCHECK(args.length() == 2); | 83 DCHECK(args.length() == 2); |
84 isolate->counters()->math_atan2()->Increment(); | 84 isolate->counters()->math_atan2_runtime()->Increment(); |
85 | |
86 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 85 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
87 CONVERT_DOUBLE_ARG_CHECKED(y, 1); | 86 CONVERT_DOUBLE_ARG_CHECKED(y, 1); |
88 double result; | 87 double result; |
89 if (std::isinf(x) && std::isinf(y)) { | 88 if (std::isinf(x) && std::isinf(y)) { |
90 // Make sure that the result in case of two infinite arguments | 89 // Make sure that the result in case of two infinite arguments |
91 // is a multiple of Pi / 4. The sign of the result is determined | 90 // is a multiple of Pi / 4. The sign of the result is determined |
92 // by the first argument (x) and the sign of the second argument | 91 // by the first argument (x) and the sign of the second argument |
93 // determines the multiplier: one or three. | 92 // determines the multiplier: one or three. |
94 int multiplier = (x < 0) ? -1 : 1; | 93 int multiplier = (x < 0) ? -1 : 1; |
95 if (y < 0) multiplier *= 3; | 94 if (y < 0) multiplier *= 3; |
96 result = multiplier * kPiDividedBy4; | 95 result = multiplier * kPiDividedBy4; |
97 } else { | 96 } else { |
98 result = std::atan2(x, y); | 97 result = std::atan2(x, y); |
99 } | 98 } |
100 return *isolate->factory()->NewNumber(result); | 99 return *isolate->factory()->NewNumber(result); |
101 } | 100 } |
102 | 101 |
103 | 102 |
104 RUNTIME_FUNCTION(Runtime_MathExpRT) { | 103 RUNTIME_FUNCTION(Runtime_MathExpRT) { |
105 HandleScope scope(isolate); | 104 HandleScope scope(isolate); |
106 DCHECK(args.length() == 1); | 105 DCHECK(args.length() == 1); |
107 isolate->counters()->math_exp()->Increment(); | 106 isolate->counters()->math_exp_runtime()->Increment(); |
108 | 107 |
109 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 108 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
110 lazily_initialize_fast_exp(isolate); | 109 lazily_initialize_fast_exp(isolate); |
111 return *isolate->factory()->NewNumber(fast_exp(x, isolate)); | 110 return *isolate->factory()->NewNumber(fast_exp(x, isolate)); |
112 } | 111 } |
113 | 112 |
114 | 113 |
115 RUNTIME_FUNCTION(Runtime_MathClz32) { | 114 RUNTIME_FUNCTION(Runtime_MathClz32) { |
116 HandleScope scope(isolate); | 115 HandleScope scope(isolate); |
117 DCHECK(args.length() == 1); | 116 DCHECK(args.length() == 1); |
118 isolate->counters()->math_clz32()->Increment(); | 117 isolate->counters()->math_clz32_runtime()->Increment(); |
119 | 118 |
120 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); | 119 CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]); |
121 return *isolate->factory()->NewNumberFromUint( | 120 return *isolate->factory()->NewNumberFromUint( |
122 base::bits::CountLeadingZeros32(x)); | 121 base::bits::CountLeadingZeros32(x)); |
123 } | 122 } |
124 | 123 |
125 | 124 |
126 RUNTIME_FUNCTION(Runtime_MathFloor) { | 125 RUNTIME_FUNCTION(Runtime_MathFloor) { |
127 HandleScope scope(isolate); | 126 HandleScope scope(isolate); |
128 DCHECK(args.length() == 1); | 127 DCHECK(args.length() == 1); |
129 isolate->counters()->math_floor()->Increment(); | 128 isolate->counters()->math_floor_runtime()->Increment(); |
130 | 129 |
131 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 130 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
132 return *isolate->factory()->NewNumber(Floor(x)); | 131 return *isolate->factory()->NewNumber(Floor(x)); |
133 } | 132 } |
134 | 133 |
135 | 134 |
136 // Slow version of Math.pow. We check for fast paths for special cases. | 135 // Slow version of Math.pow. We check for fast paths for special cases. |
137 // Used if VFP3 is not available. | 136 // Used if VFP3 is not available. |
138 RUNTIME_FUNCTION(Runtime_MathPow) { | 137 RUNTIME_FUNCTION(Runtime_MathPow) { |
139 HandleScope scope(isolate); | 138 HandleScope scope(isolate); |
140 DCHECK(args.length() == 2); | 139 DCHECK(args.length() == 2); |
141 isolate->counters()->math_pow()->Increment(); | 140 isolate->counters()->math_pow_runtime()->Increment(); |
142 | 141 |
143 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 142 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
144 | 143 |
145 // If the second argument is a smi, it is much faster to call the | 144 // If the second argument is a smi, it is much faster to call the |
146 // custom powi() function than the generic pow(). | 145 // custom powi() function than the generic pow(). |
147 if (args[1]->IsSmi()) { | 146 if (args[1]->IsSmi()) { |
148 int y = args.smi_at(1); | 147 int y = args.smi_at(1); |
149 return *isolate->factory()->NewNumber(power_double_int(x, y)); | 148 return *isolate->factory()->NewNumber(power_double_int(x, y)); |
150 } | 149 } |
151 | 150 |
152 CONVERT_DOUBLE_ARG_CHECKED(y, 1); | 151 CONVERT_DOUBLE_ARG_CHECKED(y, 1); |
153 double result = power_helper(isolate, x, y); | 152 double result = power_helper(isolate, x, y); |
154 if (std::isnan(result)) return isolate->heap()->nan_value(); | 153 if (std::isnan(result)) return isolate->heap()->nan_value(); |
155 return *isolate->factory()->NewNumber(result); | 154 return *isolate->factory()->NewNumber(result); |
156 } | 155 } |
157 | 156 |
158 | 157 |
159 // Fast version of Math.pow if we know that y is not an integer and y is not | 158 // Fast version of Math.pow if we know that y is not an integer and y is not |
160 // -0.5 or 0.5. Used as slow case from full codegen. | 159 // -0.5 or 0.5. Used as slow case from full codegen. |
161 RUNTIME_FUNCTION(Runtime_MathPowRT) { | 160 RUNTIME_FUNCTION(Runtime_MathPowRT) { |
162 HandleScope scope(isolate); | 161 HandleScope scope(isolate); |
163 DCHECK(args.length() == 2); | 162 DCHECK(args.length() == 2); |
164 isolate->counters()->math_pow()->Increment(); | 163 isolate->counters()->math_pow_runtime()->Increment(); |
165 | 164 |
166 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 165 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
167 CONVERT_DOUBLE_ARG_CHECKED(y, 1); | 166 CONVERT_DOUBLE_ARG_CHECKED(y, 1); |
168 if (y == 0) { | 167 if (y == 0) { |
169 return Smi::FromInt(1); | 168 return Smi::FromInt(1); |
170 } else { | 169 } else { |
171 double result = power_double_double(x, y); | 170 double result = power_double_double(x, y); |
172 if (std::isnan(result)) return isolate->heap()->nan_value(); | 171 if (std::isnan(result)) return isolate->heap()->nan_value(); |
173 return *isolate->factory()->NewNumber(result); | 172 return *isolate->factory()->NewNumber(result); |
174 } | 173 } |
175 } | 174 } |
176 | 175 |
177 | 176 |
178 RUNTIME_FUNCTION(Runtime_RoundNumber) { | 177 RUNTIME_FUNCTION(Runtime_RoundNumber) { |
179 HandleScope scope(isolate); | 178 HandleScope scope(isolate); |
180 DCHECK(args.length() == 1); | 179 DCHECK(args.length() == 1); |
181 CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0); | 180 CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0); |
182 isolate->counters()->math_round()->Increment(); | 181 isolate->counters()->math_round_runtime()->Increment(); |
183 | 182 |
184 if (!input->IsHeapNumber()) { | 183 if (!input->IsHeapNumber()) { |
185 DCHECK(input->IsSmi()); | 184 DCHECK(input->IsSmi()); |
186 return *input; | 185 return *input; |
187 } | 186 } |
188 | 187 |
189 Handle<HeapNumber> number = Handle<HeapNumber>::cast(input); | 188 Handle<HeapNumber> number = Handle<HeapNumber>::cast(input); |
190 | 189 |
191 double value = number->value(); | 190 double value = number->value(); |
192 int exponent = number->get_exponent(); | 191 int exponent = number->get_exponent(); |
(...skipping 21 matching lines...) Expand all Loading... |
214 if (sign && value >= -0.5) return isolate->heap()->minus_zero_value(); | 213 if (sign && value >= -0.5) return isolate->heap()->minus_zero_value(); |
215 | 214 |
216 // Do not call NumberFromDouble() to avoid extra checks. | 215 // Do not call NumberFromDouble() to avoid extra checks. |
217 return *isolate->factory()->NewNumber(Floor(value + 0.5)); | 216 return *isolate->factory()->NewNumber(Floor(value + 0.5)); |
218 } | 217 } |
219 | 218 |
220 | 219 |
221 RUNTIME_FUNCTION(Runtime_MathSqrt) { | 220 RUNTIME_FUNCTION(Runtime_MathSqrt) { |
222 HandleScope scope(isolate); | 221 HandleScope scope(isolate); |
223 DCHECK(args.length() == 1); | 222 DCHECK(args.length() == 1); |
224 isolate->counters()->math_sqrt()->Increment(); | 223 isolate->counters()->math_sqrt_runtime()->Increment(); |
225 | 224 |
226 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 225 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
227 lazily_initialize_fast_sqrt(isolate); | 226 lazily_initialize_fast_sqrt(isolate); |
228 return *isolate->factory()->NewNumber(fast_sqrt(x, isolate)); | 227 return *isolate->factory()->NewNumber(fast_sqrt(x, isolate)); |
229 } | 228 } |
230 | 229 |
231 | 230 |
232 RUNTIME_FUNCTION(Runtime_MathFround) { | 231 RUNTIME_FUNCTION(Runtime_MathFround) { |
233 HandleScope scope(isolate); | 232 HandleScope scope(isolate); |
234 DCHECK(args.length() == 1); | 233 DCHECK(args.length() == 1); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 base::RandomNumberGenerator::XorShift128(&state0, &state1); | 288 base::RandomNumberGenerator::XorShift128(&state0, &state1); |
290 array[i] = base::RandomNumberGenerator::ToDouble(state0, state1); | 289 array[i] = base::RandomNumberGenerator::ToDouble(state0, state1); |
291 } | 290 } |
292 // Persist current state. | 291 // Persist current state. |
293 array[kState0Offset] = uint64_to_double(state0); | 292 array[kState0Offset] = uint64_to_double(state0); |
294 array[kState1Offset] = uint64_to_double(state1); | 293 array[kState1Offset] = uint64_to_double(state1); |
295 return *typed_array; | 294 return *typed_array; |
296 } | 295 } |
297 } // namespace internal | 296 } // namespace internal |
298 } // namespace v8 | 297 } // namespace v8 |
OLD | NEW |