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

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

Issue 1124813005: WIP Atomics (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix AtomicsLoad type in typer.cc Created 5 years, 7 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
« no previous file with comments | « src/runtime/runtime.h ('k') | src/runtime/runtime-typedarray.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 2015 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/base/macros.h"
9 #include "src/conversions.h"
10 #include "src/runtime/runtime-utils.h"
11
12
13 namespace v8 {
14 namespace internal {
15
16 template <typename T>
17 T FromObject(Handle<Object> number);
18
19 template <>
20 inline uint32_t FromObject<uint32_t>(Handle<Object> number) {
21 return NumberToUint32(*number);
22 }
23
24 template <>
25 inline int32_t FromObject<int32_t>(Handle<Object> number) {
26 return NumberToInt32(*number);
27 }
28
29 template <>
30 inline float FromObject<float>(Handle<Object> number) {
31 return static_cast<float>(number->Number());
32 }
33
34 template <>
35 inline double FromObject<double>(Handle<Object> number) {
36 return number->Number();
37 }
38
39 template <typename T, typename F>
40 inline T ToAtomic(F from) {
41 return static_cast<T>(from);
42 }
43
44 template <>
45 inline uint32_t ToAtomic<uint32_t, float>(float from) {
46 return bit_cast<uint32_t, float>(from);
47 }
48
49 template <>
50 inline uint64_t ToAtomic<uint64_t, double>(double from) {
51 return bit_cast<uint64_t, double>(from);
52 }
53
54 template <typename T, typename F>
55 inline T FromAtomic(F from) {
56 return static_cast<T>(from);
57 }
58
59 template <>
60 inline float FromAtomic<float, uint32_t>(uint32_t from) {
61 return bit_cast<float, uint32_t>(from);
62 }
63
64 template <>
65 inline double FromAtomic<double, uint64_t>(uint64_t from) {
66 return bit_cast<double, uint64_t>(from);
67 }
68
69 template <typename T>
70 inline Object* ToObject(Isolate* isolate, T t);
71
72 template <>
73 inline Object* ToObject<int8_t>(Isolate* isolate, int8_t t) {
74 return Smi::FromInt(t);
75 }
76
77 template <>
78 inline Object* ToObject<uint8_t>(Isolate* isolate, uint8_t t) {
79 return Smi::FromInt(t);
80 }
81
82 template <>
83 inline Object* ToObject<int16_t>(Isolate* isolate, int16_t t) {
84 return Smi::FromInt(t);
85 }
86
87 template <>
88 inline Object* ToObject<uint16_t>(Isolate* isolate, uint16_t t) {
89 return Smi::FromInt(t);
90 }
91
92 template <>
93 inline Object* ToObject<int32_t>(Isolate* isolate, int32_t t) {
94 return *isolate->factory()->NewNumber(t);
95 }
96
97 template <>
98 inline Object* ToObject<uint32_t>(Isolate* isolate, uint32_t t) {
99 return *isolate->factory()->NewNumber(t);
100 }
101
102 template <>
103 inline Object* ToObject<float>(Isolate* isolate, float t) {
104 return *isolate->factory()->NewNumber(t);
105 }
106
107 template <>
108 inline Object* ToObject<double>(Isolate* isolate, double t) {
109 return *isolate->factory()->NewNumber(t);
110 }
111
112 template <typename T>
113 struct FromObjectTraits {};
114
115 template <>
116 struct FromObjectTraits<int8_t> {
117 typedef int32_t convert_type;
118 typedef int8_t atomic_type;
119 };
120
121 template <>
122 struct FromObjectTraits<uint8_t> {
123 typedef uint32_t convert_type;
124 typedef uint8_t atomic_type;
125 };
126
127 template <>
128 struct FromObjectTraits<int16_t> {
129 typedef int32_t convert_type;
130 typedef int16_t atomic_type;
131 };
132
133 template <>
134 struct FromObjectTraits<uint16_t> {
135 typedef uint32_t convert_type;
136 typedef uint16_t atomic_type;
137 };
138
139 template <>
140 struct FromObjectTraits<int32_t> {
141 typedef int32_t convert_type;
142 typedef int32_t atomic_type;
143 };
144
145 template <>
146 struct FromObjectTraits<uint32_t> {
147 typedef uint32_t convert_type;
148 typedef uint32_t atomic_type;
149 };
150
151 template <>
152 struct FromObjectTraits<float> {
153 typedef float convert_type;
154 typedef uint32_t atomic_type;
155 };
156
157 template <>
158 struct FromObjectTraits<double> {
159 typedef double convert_type;
160 typedef uint64_t atomic_type;
161 };
162
163
164 template <typename T>
165 inline Object* CompareExchange(Isolate* isolate, void* buffer, size_t index,
166 Handle<Object> oldobj, Handle<Object> newobj) {
167 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
168 typedef typename FromObjectTraits<T>::convert_type convert_type;
169 atomic_type oldval = ToAtomic<atomic_type>(FromObject<convert_type>(oldobj));
170 atomic_type newval = ToAtomic<atomic_type>(FromObject<convert_type>(newobj));
171 __atomic_compare_exchange_n(static_cast<atomic_type*>(buffer) + index,
172 &oldval, newval, 0, __ATOMIC_SEQ_CST,
173 __ATOMIC_SEQ_CST);
174 return ToObject<T>(isolate, FromAtomic<T>(oldval));
175 }
176
177
178 template <typename T>
179 inline Object* Load(Isolate* isolate, void* buffer, size_t index) {
180 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
181 atomic_type result;
182 __atomic_load(static_cast<atomic_type*>(buffer) + index, &result,
183 __ATOMIC_SEQ_CST);
184 return ToObject<T>(isolate, FromAtomic<T>(result));
185 }
186
187
188 template <typename T>
189 inline Object* Store(Isolate* isolate, void* buffer, size_t index,
190 Handle<Object> obj) {
191 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
192 typedef typename FromObjectTraits<T>::convert_type convert_type;
193 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj));
194 __atomic_store_n(static_cast<atomic_type*>(buffer) + index, value,
195 __ATOMIC_SEQ_CST);
196 return *obj;
197 }
198
199
200 template <typename T>
201 inline Object* Add(Isolate* isolate, void* buffer, size_t index,
202 Handle<Object> obj) {
203 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
204 typedef typename FromObjectTraits<T>::convert_type convert_type;
205 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj));
206 atomic_type result = __atomic_fetch_add(
207 static_cast<atomic_type*>(buffer) + index, value, __ATOMIC_SEQ_CST);
208 return ToObject<T>(isolate, FromAtomic<T>(result));
209 }
210
211
212 template <typename T>
213 inline Object* Sub(Isolate* isolate, void* buffer, size_t index,
214 Handle<Object> obj) {
215 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
216 typedef typename FromObjectTraits<T>::convert_type convert_type;
217 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj));
218 atomic_type result = __atomic_fetch_sub(
219 static_cast<atomic_type*>(buffer) + index, value, __ATOMIC_SEQ_CST);
220 return ToObject<T>(isolate, FromAtomic<T>(result));
221 }
222
223
224 template <typename T>
225 inline Object* And(Isolate* isolate, void* buffer, size_t index,
226 Handle<Object> obj) {
227 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
228 typedef typename FromObjectTraits<T>::convert_type convert_type;
229 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj));
230 atomic_type result = __atomic_fetch_and(
231 static_cast<atomic_type*>(buffer) + index, value, __ATOMIC_SEQ_CST);
232 return ToObject<T>(isolate, FromAtomic<T>(result));
233 }
234
235
236 template <typename T>
237 inline Object* Or(Isolate* isolate, void* buffer, size_t index,
238 Handle<Object> obj) {
239 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
240 typedef typename FromObjectTraits<T>::convert_type convert_type;
241 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj));
242 atomic_type result = __atomic_fetch_or(
243 static_cast<atomic_type*>(buffer) + index, value, __ATOMIC_SEQ_CST);
244 return ToObject<T>(isolate, FromAtomic<T>(result));
245 }
246
247
248 template <typename T>
249 inline Object* Xor(Isolate* isolate, void* buffer, size_t index,
250 Handle<Object> obj) {
251 typedef typename FromObjectTraits<T>::atomic_type atomic_type;
252 typedef typename FromObjectTraits<T>::convert_type convert_type;
253 atomic_type value = ToAtomic<atomic_type>(FromObject<convert_type>(obj));
254 atomic_type result = __atomic_fetch_xor(
255 static_cast<atomic_type*>(buffer) + index, value, __ATOMIC_SEQ_CST);
256 return ToObject<T>(isolate, FromAtomic<T>(result));
257 }
258
259
260 // Duplicated from objects.h
261 // V has parameters (Type, type, TYPE, C type, element_size)
262 #define INTEGER_TYPED_ARRAYS(V) \
263 V(Uint8, uint8, UINT8, uint8_t, 1) \
264 V(Int8, int8, INT8, int8_t, 1) \
265 V(Uint16, uint16, UINT16, uint16_t, 2) \
266 V(Int16, int16, INT16, int16_t, 2) \
267 V(Uint32, uint32, UINT32, uint32_t, 4) \
268 V(Int32, int32, INT32, int32_t, 4) \
269 V(Uint8Clamped, uint8_clamped, UINT8_CLAMPED, uint8_t, 1)
270
271
272 RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) {
273 HandleScope scope(isolate);
274 DCHECK(args.length() == 4);
275 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
276 CONVERT_SIZE_ARG_CHECKED(index, 1);
277 CONVERT_NUMBER_ARG_HANDLE_CHECKED(oldobj, 2);
278 CONVERT_NUMBER_ARG_HANDLE_CHECKED(newobj, 3);
279
280 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
281 size_t sta_length = NumberToSize(isolate, sta->length());
282
283 DCHECK(typedarray->is_shared());
284 DCHECK(index < sta_length);
285
286 void* buffer = sta->GetBuffer()->backing_store();
287
288 switch (typedarray->type()) {
289 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
290 case kExternal##Type##Array: \
291 return CompareExchange<ctype>(isolate, buffer, index, oldobj, newobj);
292
293 TYPED_ARRAYS(TYPED_ARRAY_CASE)
294 #undef TYPED_ARRAY_CASE
295
296 default:
297 break;
298 }
299
300 UNREACHABLE();
301 return isolate->heap()->undefined_value();
302 }
303
304
305 RUNTIME_FUNCTION(Runtime_AtomicsLoad) {
306 HandleScope scope(isolate);
307 DCHECK(args.length() == 2);
308 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
309 CONVERT_SIZE_ARG_CHECKED(index, 1);
310
311 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
312 size_t sta_length = NumberToSize(isolate, sta->length());
313
314 DCHECK(typedarray->is_shared());
315 DCHECK(index < sta_length);
316
317 void* buffer = sta->GetBuffer()->backing_store();
318
319 switch (typedarray->type()) {
320 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
321 case kExternal##Type##Array: \
322 return Load<ctype>(isolate, buffer, index);
323
324 TYPED_ARRAYS(TYPED_ARRAY_CASE)
325 #undef TYPED_ARRAY_CASE
326
327 default:
328 break;
329 }
330
331 UNREACHABLE();
332 return isolate->heap()->undefined_value();
333 }
334
335
336 RUNTIME_FUNCTION(Runtime_AtomicsStore) {
337 HandleScope scope(isolate);
338 DCHECK(args.length() == 3);
339 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
340 CONVERT_SIZE_ARG_CHECKED(index, 1);
341 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
342
343 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
344 size_t sta_length = NumberToSize(isolate, sta->length());
345
346 DCHECK(typedarray->is_shared());
347 DCHECK(index < sta_length);
348
349 void* buffer = sta->GetBuffer()->backing_store();
350
351 switch (typedarray->type()) {
352 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
353 case kExternal##Type##Array: \
354 return Store<ctype>(isolate, buffer, index, value);
355
356 TYPED_ARRAYS(TYPED_ARRAY_CASE)
357 #undef TYPED_ARRAY_CASE
358
359 default:
360 break;
361 }
362
363 UNREACHABLE();
364 return isolate->heap()->undefined_value();
365 }
366
367
368 RUNTIME_FUNCTION(Runtime_AtomicsAdd) {
369 HandleScope scope(isolate);
370 DCHECK(args.length() == 3);
371 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
372 CONVERT_SIZE_ARG_CHECKED(index, 1);
373 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
374
375 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
376 size_t sta_length = NumberToSize(isolate, sta->length());
377
378 DCHECK(typedarray->is_shared());
379 DCHECK(index < sta_length);
380
381 void* buffer = sta->GetBuffer()->backing_store();
382
383 switch (typedarray->type()) {
384 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
385 case kExternal##Type##Array: \
386 return Add<ctype>(isolate, buffer, index, value);
387
388 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
389 #undef TYPED_ARRAY_CASE
390
391 case kExternalFloat32Array:
392 case kExternalFloat64Array:
393 default:
394 break;
395 }
396
397 UNREACHABLE();
398 return isolate->heap()->undefined_value();
399 }
400
401
402 RUNTIME_FUNCTION(Runtime_AtomicsSub) {
403 HandleScope scope(isolate);
404 DCHECK(args.length() == 3);
405 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
406 CONVERT_SIZE_ARG_CHECKED(index, 1);
407 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
408
409 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
410 size_t sta_length = NumberToSize(isolate, sta->length());
411
412 DCHECK(typedarray->is_shared());
413 DCHECK(index < sta_length);
414
415 void* buffer = sta->GetBuffer()->backing_store();
416
417 switch (typedarray->type()) {
418 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
419 case kExternal##Type##Array: \
420 return Sub<ctype>(isolate, buffer, index, value);
421
422 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
423 #undef TYPED_ARRAY_CASE
424
425 case kExternalFloat32Array:
426 case kExternalFloat64Array:
427 default:
428 break;
429 }
430
431 UNREACHABLE();
432 return isolate->heap()->undefined_value();
433 }
434
435
436 RUNTIME_FUNCTION(Runtime_AtomicsAnd) {
437 HandleScope scope(isolate);
438 DCHECK(args.length() == 3);
439 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
440 CONVERT_SIZE_ARG_CHECKED(index, 1);
441 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
442
443 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
444 size_t sta_length = NumberToSize(isolate, sta->length());
445
446 DCHECK(typedarray->is_shared());
447 DCHECK(index < sta_length);
448
449 void* buffer = sta->GetBuffer()->backing_store();
450
451 switch (typedarray->type()) {
452 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
453 case kExternal##Type##Array: \
454 return And<ctype>(isolate, buffer, index, value);
455
456 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
457 #undef TYPED_ARRAY_CASE
458
459 case kExternalFloat32Array:
460 case kExternalFloat64Array:
461 default:
462 break;
463 }
464
465 UNREACHABLE();
466 return isolate->heap()->undefined_value();
467 }
468
469
470 RUNTIME_FUNCTION(Runtime_AtomicsOr) {
471 HandleScope scope(isolate);
472 DCHECK(args.length() == 3);
473 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
474 CONVERT_SIZE_ARG_CHECKED(index, 1);
475 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
476
477 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
478 size_t sta_length = NumberToSize(isolate, sta->length());
479
480 DCHECK(typedarray->is_shared());
481 DCHECK(index < sta_length);
482
483 void* buffer = sta->GetBuffer()->backing_store();
484
485 switch (typedarray->type()) {
486 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
487 case kExternal##Type##Array: \
488 return Or<ctype>(isolate, buffer, index, value);
489
490 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
491 #undef TYPED_ARRAY_CASE
492
493 case kExternalFloat32Array:
494 case kExternalFloat64Array:
495 default:
496 break;
497 }
498
499 UNREACHABLE();
500 return isolate->heap()->undefined_value();
501 }
502
503
504 RUNTIME_FUNCTION(Runtime_AtomicsXor) {
505 HandleScope scope(isolate);
506 DCHECK(args.length() == 3);
507 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
508 CONVERT_SIZE_ARG_CHECKED(index, 1);
509 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);
510
511 Handle<JSTypedArray> sta(JSTypedArray::cast(*typedarray));
512 size_t sta_length = NumberToSize(isolate, sta->length());
513
514 DCHECK(typedarray->is_shared());
515 DCHECK(index < sta_length);
516
517 void* buffer = sta->GetBuffer()->backing_store();
518
519 switch (typedarray->type()) {
520 #define TYPED_ARRAY_CASE(Type, typeName, TYPE, ctype, size) \
521 case kExternal##Type##Array: \
522 return Xor<ctype>(isolate, buffer, index, value);
523
524 INTEGER_TYPED_ARRAYS(TYPED_ARRAY_CASE)
525 #undef TYPED_ARRAY_CASE
526
527 case kExternalFloat32Array:
528 case kExternalFloat64Array:
529 default:
530 break;
531 }
532
533 UNREACHABLE();
534 return isolate->heap()->undefined_value();
535 }
536
537
538 RUNTIME_FUNCTION(Runtime_AtomicsExchange) {
539 HandleScope scope(isolate);
540 DCHECK(args.length() == 3);
541 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, typedarray, 0);
542 CONVERT_SIZE_ARG_CHECKED(index, 1);
543 CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 1);
544 DCHECK(typedarray->is_shared());
545 (void)index;
546 (void)value;
547 return isolate->heap()->undefined_value();
548 }
549
550
551 RUNTIME_FUNCTION(Runtime_AtomicsIsLockFree) {
552 return isolate->heap()->true_value();
553 }
554 }
555 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime/runtime.h ('k') | src/runtime/runtime-typedarray.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698