Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: src/runtime/runtime-maths.cc

Issue 598913004: Split more runtime functions into seperate files. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime/runtime-compiler.cc ('k') | src/runtime/runtime-numbers.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #include "src/arguments.h"
8 #include "src/assembler.h"
9 #include "src/codegen.h"
10 #include "src/runtime/runtime.h"
11 #include "src/runtime/runtime-utils.h"
12 #include "third_party/fdlibm/fdlibm.h"
13
14
15 namespace v8 {
16 namespace internal {
17
18 #define RUNTIME_UNARY_MATH(Name, name) \
19 RUNTIME_FUNCTION(Runtime_Math##Name) { \
20 HandleScope scope(isolate); \
21 DCHECK(args.length() == 1); \
22 isolate->counters()->math_##name()->Increment(); \
23 CONVERT_DOUBLE_ARG_CHECKED(x, 0); \
24 return *isolate->factory()->NewHeapNumber(std::name(x)); \
25 }
26
27 RUNTIME_UNARY_MATH(Acos, acos)
28 RUNTIME_UNARY_MATH(Asin, asin)
29 RUNTIME_UNARY_MATH(Atan, atan)
30 RUNTIME_UNARY_MATH(LogRT, log)
31 #undef RUNTIME_UNARY_MATH
32
33
34 RUNTIME_FUNCTION(Runtime_DoubleHi) {
35 HandleScope scope(isolate);
36 DCHECK(args.length() == 1);
37 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
38 uint64_t integer = double_to_uint64(x);
39 integer = (integer >> 32) & 0xFFFFFFFFu;
40 return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
41 }
42
43
44 RUNTIME_FUNCTION(Runtime_DoubleLo) {
45 HandleScope scope(isolate);
46 DCHECK(args.length() == 1);
47 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
48 return *isolate->factory()->NewNumber(
49 static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
50 }
51
52
53 RUNTIME_FUNCTION(Runtime_ConstructDouble) {
54 HandleScope scope(isolate);
55 DCHECK(args.length() == 2);
56 CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
57 CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
58 uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
59 return *isolate->factory()->NewNumber(uint64_to_double(result));
60 }
61
62
63 RUNTIME_FUNCTION(Runtime_RemPiO2) {
64 HandleScope handle_scope(isolate);
65 DCHECK(args.length() == 1);
66 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
67 Factory* factory = isolate->factory();
68 double y[2];
69 int n = fdlibm::rempio2(x, y);
70 Handle<FixedArray> array = factory->NewFixedArray(3);
71 Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
72 Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
73 array->set(0, Smi::FromInt(n));
74 array->set(1, *y0);
75 array->set(2, *y1);
76 return *factory->NewJSArrayWithElements(array);
77 }
78
79
80 static const double kPiDividedBy4 = 0.78539816339744830962;
81
82
83 RUNTIME_FUNCTION(Runtime_MathAtan2) {
84 HandleScope scope(isolate);
85 DCHECK(args.length() == 2);
86 isolate->counters()->math_atan2()->Increment();
87
88 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
89 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
90 double result;
91 if (std::isinf(x) && std::isinf(y)) {
92 // Make sure that the result in case of two infinite arguments
93 // is a multiple of Pi / 4. The sign of the result is determined
94 // by the first argument (x) and the sign of the second argument
95 // determines the multiplier: one or three.
96 int multiplier = (x < 0) ? -1 : 1;
97 if (y < 0) multiplier *= 3;
98 result = multiplier * kPiDividedBy4;
99 } else {
100 result = std::atan2(x, y);
101 }
102 return *isolate->factory()->NewNumber(result);
103 }
104
105
106 RUNTIME_FUNCTION(Runtime_MathExpRT) {
107 HandleScope scope(isolate);
108 DCHECK(args.length() == 1);
109 isolate->counters()->math_exp()->Increment();
110
111 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
112 lazily_initialize_fast_exp();
113 return *isolate->factory()->NewNumber(fast_exp(x));
114 }
115
116
117 RUNTIME_FUNCTION(Runtime_MathFloorRT) {
118 HandleScope scope(isolate);
119 DCHECK(args.length() == 1);
120 isolate->counters()->math_floor()->Increment();
121
122 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
123 return *isolate->factory()->NewNumber(Floor(x));
124 }
125
126
127 // Slow version of Math.pow. We check for fast paths for special cases.
128 // Used if VFP3 is not available.
129 RUNTIME_FUNCTION(Runtime_MathPowSlow) {
130 HandleScope scope(isolate);
131 DCHECK(args.length() == 2);
132 isolate->counters()->math_pow()->Increment();
133
134 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
135
136 // If the second argument is a smi, it is much faster to call the
137 // custom powi() function than the generic pow().
138 if (args[1]->IsSmi()) {
139 int y = args.smi_at(1);
140 return *isolate->factory()->NewNumber(power_double_int(x, y));
141 }
142
143 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
144 double result = power_helper(x, y);
145 if (std::isnan(result)) return isolate->heap()->nan_value();
146 return *isolate->factory()->NewNumber(result);
147 }
148
149
150 // Fast version of Math.pow if we know that y is not an integer and y is not
151 // -0.5 or 0.5. Used as slow case from full codegen.
152 RUNTIME_FUNCTION(Runtime_MathPowRT) {
153 HandleScope scope(isolate);
154 DCHECK(args.length() == 2);
155 isolate->counters()->math_pow()->Increment();
156
157 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
158 CONVERT_DOUBLE_ARG_CHECKED(y, 1);
159 if (y == 0) {
160 return Smi::FromInt(1);
161 } else {
162 double result = power_double_double(x, y);
163 if (std::isnan(result)) return isolate->heap()->nan_value();
164 return *isolate->factory()->NewNumber(result);
165 }
166 }
167
168
169 RUNTIME_FUNCTION(Runtime_RoundNumber) {
170 HandleScope scope(isolate);
171 DCHECK(args.length() == 1);
172 CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
173 isolate->counters()->math_round()->Increment();
174
175 if (!input->IsHeapNumber()) {
176 DCHECK(input->IsSmi());
177 return *input;
178 }
179
180 Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
181
182 double value = number->value();
183 int exponent = number->get_exponent();
184 int sign = number->get_sign();
185
186 if (exponent < -1) {
187 // Number in range ]-0.5..0.5[. These always round to +/-zero.
188 if (sign) return isolate->heap()->minus_zero_value();
189 return Smi::FromInt(0);
190 }
191
192 // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
193 // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
194 // argument holds for 32-bit smis).
195 if (!sign && exponent < kSmiValueSize - 2) {
196 return Smi::FromInt(static_cast<int>(value + 0.5));
197 }
198
199 // If the magnitude is big enough, there's no place for fraction part. If we
200 // try to add 0.5 to this number, 1.0 will be added instead.
201 if (exponent >= 52) {
202 return *number;
203 }
204
205 if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
206
207 // Do not call NumberFromDouble() to avoid extra checks.
208 return *isolate->factory()->NewNumber(Floor(value + 0.5));
209 }
210
211
212 RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
213 HandleScope scope(isolate);
214 DCHECK(args.length() == 1);
215 isolate->counters()->math_sqrt()->Increment();
216
217 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
218 return *isolate->factory()->NewNumber(fast_sqrt(x));
219 }
220
221
222 RUNTIME_FUNCTION(Runtime_MathFround) {
223 HandleScope scope(isolate);
224 DCHECK(args.length() == 1);
225
226 CONVERT_DOUBLE_ARG_CHECKED(x, 0);
227 float xf = DoubleToFloat32(x);
228 return *isolate->factory()->NewNumber(xf);
229 }
230
231
232 RUNTIME_FUNCTION(RuntimeReference_MathPow) {
233 SealHandleScope shs(isolate);
234 return __RT_impl_Runtime_MathPowSlow(args, isolate);
235 }
236
237
238 RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
239 SealHandleScope shs(isolate);
240 DCHECK(args.length() == 1);
241 CONVERT_ARG_CHECKED(Object, obj, 0);
242 if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
243 HeapNumber* number = HeapNumber::cast(obj);
244 return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
245 }
246 }
247 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime/runtime-compiler.cc ('k') | src/runtime/runtime-numbers.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698