Line data Source code
1 : // Copyright 2017 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/builtins/builtins-utils-gen.h"
6 : #include "src/builtins/builtins.h"
7 : #include "src/code-stub-assembler.h"
8 : #include "src/objects.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 : using compiler::Node;
14 :
15 : class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler {
16 : public:
17 : explicit SharedArrayBufferBuiltinsAssembler(
18 : compiler::CodeAssemblerState* state)
19 279 : : CodeStubAssembler(state) {}
20 :
21 : protected:
22 : typedef Node* (CodeAssembler::*AssemblerFunction)(MachineType type,
23 : Node* base, Node* offset,
24 : Node* value);
25 : void ValidateSharedTypedArray(Node* tagged, Node* context,
26 : Node** out_instance_type,
27 : Node** out_backing_store);
28 : Node* ConvertTaggedAtomicIndexToWord32(Node* tagged, Node* context,
29 : Node** number_index);
30 : void ValidateAtomicIndex(Node* array, Node* index_word, Node* context);
31 : #if DEBUG
32 : void DebugSanityCheckAtomicIndex(Node* array, Node* index_word,
33 : Node* context);
34 : #endif
35 : void AtomicBinopBuiltinCommon(Node* array, Node* index, Node* value,
36 : Node* context, AssemblerFunction function,
37 : Runtime::FunctionId runtime_function);
38 : };
39 :
40 279 : void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray(
41 : Node* tagged, Node* context, Node** out_instance_type,
42 : Node** out_backing_store) {
43 558 : Label not_float_or_clamped(this), invalid(this);
44 :
45 : // Fail if it is not a heap object.
46 558 : GotoIf(TaggedIsSmi(tagged), &invalid);
47 :
48 : // Fail if the array's instance type is not JSTypedArray.
49 279 : GotoIfNot(InstanceTypeEqual(LoadInstanceType(tagged), JS_TYPED_ARRAY_TYPE),
50 837 : &invalid);
51 :
52 : // Fail if the array's JSArrayBuffer is not shared.
53 : Node* array_buffer = LoadObjectField(tagged, JSTypedArray::kBufferOffset);
54 : Node* bitfield = LoadObjectField(array_buffer, JSArrayBuffer::kBitFieldOffset,
55 279 : MachineType::Uint32());
56 279 : GotoIfNot(IsSetWord32<JSArrayBuffer::IsShared>(bitfield), &invalid);
57 :
58 : // Fail if the array's element type is float32, float64 or clamped.
59 837 : Node* elements_instance_type = LoadInstanceType(LoadElements(tagged));
60 : STATIC_ASSERT(FIXED_INT8_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
61 : STATIC_ASSERT(FIXED_INT16_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
62 : STATIC_ASSERT(FIXED_INT32_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
63 : STATIC_ASSERT(FIXED_UINT8_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
64 : STATIC_ASSERT(FIXED_UINT16_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
65 : STATIC_ASSERT(FIXED_UINT32_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE);
66 : Branch(Int32LessThan(elements_instance_type,
67 558 : Int32Constant(FIXED_FLOAT32_ARRAY_TYPE)),
68 558 : ¬_float_or_clamped, &invalid);
69 :
70 279 : BIND(&invalid);
71 : {
72 : CallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, context,
73 : tagged);
74 279 : Unreachable();
75 : }
76 :
77 279 : BIND(¬_float_or_clamped);
78 279 : *out_instance_type = elements_instance_type;
79 :
80 : Node* backing_store =
81 : LoadObjectField(array_buffer, JSArrayBuffer::kBackingStoreOffset);
82 : Node* byte_offset = ChangeUint32ToWord(TruncateTaggedToWord32(
83 837 : context, LoadObjectField(tagged, JSArrayBufferView::kByteOffsetOffset)));
84 558 : *out_backing_store =
85 1116 : IntPtrAdd(BitcastTaggedToWord(backing_store), byte_offset);
86 279 : }
87 :
88 : // https://tc39.github.io/ecmascript_sharedmem/shmem.html#Atomics.ValidateAtomicAccess
89 279 : Node* SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32(
90 : Node* tagged, Node* context, Node** number_index) {
91 279 : VARIABLE(var_result, MachineRepresentation::kWord32);
92 279 : Label done(this), range_error(this);
93 :
94 : // Returns word32 since index cannot be longer than a TypedArray length,
95 : // which has a uint32 maximum.
96 : // The |number_index| output parameter is used only for architectures that
97 : // don't currently have a TF implementation and forward to runtime functions
98 : // instead; they expect the value has already been coerced to an integer.
99 279 : *number_index = ToSmiIndex(tagged, context, &range_error);
100 558 : var_result.Bind(SmiToWord32(*number_index));
101 279 : Goto(&done);
102 :
103 279 : BIND(&range_error);
104 : {
105 : CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context);
106 279 : Unreachable();
107 : }
108 :
109 279 : BIND(&done);
110 558 : return var_result.value();
111 : }
112 :
113 279 : void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex(Node* array,
114 : Node* index_word,
115 : Node* context) {
116 : // Check if the index is in bounds. If not, throw RangeError.
117 279 : Label check_passed(this);
118 : Node* array_length_word32 = TruncateTaggedToWord32(
119 558 : context, LoadObjectField(array, JSTypedArray::kLengthOffset));
120 558 : GotoIf(Uint32LessThan(index_word, array_length_word32), &check_passed);
121 :
122 : CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context);
123 279 : Unreachable();
124 :
125 279 : BIND(&check_passed);
126 279 : }
127 :
128 : #if DEBUG
129 : void SharedArrayBufferBuiltinsAssembler::DebugSanityCheckAtomicIndex(
130 : Node* array, Node* index_word, Node* context) {
131 : // In Debug mode, we re-validate the index as a sanity check because
132 : // ToInteger above calls out to JavaScript. A SharedArrayBuffer can't be
133 : // neutered and the TypedArray length can't change either, so skipping this
134 : // check in Release mode is safe.
135 : CSA_ASSERT(
136 : this,
137 : Uint32LessThan(
138 : index_word,
139 : TruncateTaggedToWord32(
140 : context, LoadObjectField(array, JSTypedArray::kLengthOffset))));
141 : }
142 : #endif
143 :
144 124 : TF_BUILTIN(AtomicsLoad, SharedArrayBufferBuiltinsAssembler) {
145 : Node* array = Parameter(Descriptor::kArray);
146 : Node* index = Parameter(Descriptor::kIndex);
147 : Node* context = Parameter(Descriptor::kContext);
148 :
149 : Node* instance_type;
150 : Node* backing_store;
151 31 : ValidateSharedTypedArray(array, context, &instance_type, &backing_store);
152 :
153 : Node* index_integer;
154 : Node* index_word32 =
155 31 : ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
156 31 : ValidateAtomicIndex(array, index_word32, context);
157 62 : Node* index_word = ChangeUint32ToWord(index_word32);
158 :
159 31 : Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
160 31 : other(this);
161 : int32_t case_values[] = {
162 : FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE,
163 : FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE,
164 31 : };
165 : Label* case_labels[] = {
166 : &i8, &u8, &i16, &u16, &i32, &u32,
167 31 : };
168 : Switch(instance_type, &other, case_values, case_labels,
169 31 : arraysize(case_labels));
170 :
171 31 : BIND(&i8);
172 : Return(SmiFromWord32(
173 93 : AtomicLoad(MachineType::Int8(), backing_store, index_word)));
174 :
175 31 : BIND(&u8);
176 : Return(SmiFromWord32(
177 93 : AtomicLoad(MachineType::Uint8(), backing_store, index_word)));
178 :
179 31 : BIND(&i16);
180 : Return(SmiFromWord32(
181 124 : AtomicLoad(MachineType::Int16(), backing_store, WordShl(index_word, 1))));
182 :
183 31 : BIND(&u16);
184 : Return(SmiFromWord32(AtomicLoad(MachineType::Uint16(), backing_store,
185 124 : WordShl(index_word, 1))));
186 :
187 31 : BIND(&i32);
188 : Return(ChangeInt32ToTagged(
189 124 : AtomicLoad(MachineType::Int32(), backing_store, WordShl(index_word, 2))));
190 :
191 31 : BIND(&u32);
192 : Return(ChangeUint32ToTagged(AtomicLoad(MachineType::Uint32(), backing_store,
193 124 : WordShl(index_word, 2))));
194 :
195 : // This shouldn't happen, we've already validated the type.
196 31 : BIND(&other);
197 62 : Unreachable();
198 31 : }
199 :
200 124 : TF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) {
201 : Node* array = Parameter(Descriptor::kArray);
202 : Node* index = Parameter(Descriptor::kIndex);
203 : Node* value = Parameter(Descriptor::kValue);
204 : Node* context = Parameter(Descriptor::kContext);
205 :
206 : Node* instance_type;
207 : Node* backing_store;
208 31 : ValidateSharedTypedArray(array, context, &instance_type, &backing_store);
209 :
210 : Node* index_integer;
211 : Node* index_word32 =
212 31 : ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
213 31 : ValidateAtomicIndex(array, index_word32, context);
214 62 : Node* index_word = ChangeUint32ToWord(index_word32);
215 :
216 62 : Node* value_integer = ToInteger(context, value);
217 31 : Node* value_word32 = TruncateTaggedToWord32(context, value_integer);
218 :
219 : #if DEBUG
220 : DebugSanityCheckAtomicIndex(array, index_word32, context);
221 : #endif
222 :
223 31 : Label u8(this), u16(this), u32(this), other(this);
224 : int32_t case_values[] = {
225 : FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE,
226 : FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE,
227 31 : };
228 : Label* case_labels[] = {
229 : &u8, &u8, &u16, &u16, &u32, &u32,
230 31 : };
231 : Switch(instance_type, &other, case_values, case_labels,
232 31 : arraysize(case_labels));
233 :
234 31 : BIND(&u8);
235 : AtomicStore(MachineRepresentation::kWord8, backing_store, index_word,
236 31 : value_word32);
237 31 : Return(value_integer);
238 :
239 31 : BIND(&u16);
240 : AtomicStore(MachineRepresentation::kWord16, backing_store,
241 62 : WordShl(index_word, 1), value_word32);
242 31 : Return(value_integer);
243 :
244 31 : BIND(&u32);
245 : AtomicStore(MachineRepresentation::kWord32, backing_store,
246 62 : WordShl(index_word, 2), value_word32);
247 31 : Return(value_integer);
248 :
249 : // This shouldn't happen, we've already validated the type.
250 31 : BIND(&other);
251 62 : Unreachable();
252 31 : }
253 :
254 124 : TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) {
255 : Node* array = Parameter(Descriptor::kArray);
256 : Node* index = Parameter(Descriptor::kIndex);
257 : Node* value = Parameter(Descriptor::kValue);
258 : Node* context = Parameter(Descriptor::kContext);
259 :
260 : Node* instance_type;
261 : Node* backing_store;
262 31 : ValidateSharedTypedArray(array, context, &instance_type, &backing_store);
263 :
264 : Node* index_integer;
265 : Node* index_word32 =
266 31 : ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
267 31 : ValidateAtomicIndex(array, index_word32, context);
268 :
269 62 : Node* value_integer = ToInteger(context, value);
270 :
271 : #if DEBUG
272 : DebugSanityCheckAtomicIndex(array, index_word32, context);
273 : #endif
274 :
275 : #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
276 : Return(CallRuntime(Runtime::kAtomicsExchange, context, array, index_integer,
277 : value_integer));
278 : #else
279 62 : Node* index_word = ChangeUint32ToWord(index_word32);
280 :
281 31 : Node* value_word32 = TruncateTaggedToWord32(context, value_integer);
282 :
283 31 : Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
284 31 : other(this);
285 : int32_t case_values[] = {
286 : FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE,
287 : FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE,
288 31 : };
289 : Label* case_labels[] = {
290 : &i8, &u8, &i16, &u16, &i32, &u32,
291 31 : };
292 : Switch(instance_type, &other, case_values, case_labels,
293 31 : arraysize(case_labels));
294 :
295 31 : BIND(&i8);
296 : Return(SmiFromWord32(AtomicExchange(MachineType::Int8(), backing_store,
297 93 : index_word, value_word32)));
298 :
299 31 : BIND(&u8);
300 : Return(SmiFromWord32(AtomicExchange(MachineType::Uint8(), backing_store,
301 93 : index_word, value_word32)));
302 :
303 31 : BIND(&i16);
304 : Return(SmiFromWord32(AtomicExchange(MachineType::Int16(), backing_store,
305 124 : WordShl(index_word, 1), value_word32)));
306 :
307 31 : BIND(&u16);
308 : Return(SmiFromWord32(AtomicExchange(MachineType::Uint16(), backing_store,
309 124 : WordShl(index_word, 1), value_word32)));
310 :
311 31 : BIND(&i32);
312 : Return(ChangeInt32ToTagged(AtomicExchange(MachineType::Int32(), backing_store,
313 31 : WordShl(index_word, 2),
314 124 : value_word32)));
315 :
316 31 : BIND(&u32);
317 : Return(ChangeUint32ToTagged(
318 : AtomicExchange(MachineType::Uint32(), backing_store,
319 124 : WordShl(index_word, 2), value_word32)));
320 :
321 : // This shouldn't happen, we've already validated the type.
322 31 : BIND(&other);
323 62 : Unreachable();
324 : #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
325 31 : }
326 :
327 124 : TF_BUILTIN(AtomicsCompareExchange, SharedArrayBufferBuiltinsAssembler) {
328 : Node* array = Parameter(Descriptor::kArray);
329 : Node* index = Parameter(Descriptor::kIndex);
330 : Node* old_value = Parameter(Descriptor::kOldValue);
331 : Node* new_value = Parameter(Descriptor::kNewValue);
332 : Node* context = Parameter(Descriptor::kContext);
333 :
334 : Node* instance_type;
335 : Node* backing_store;
336 31 : ValidateSharedTypedArray(array, context, &instance_type, &backing_store);
337 :
338 : Node* index_integer;
339 : Node* index_word32 =
340 31 : ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
341 31 : ValidateAtomicIndex(array, index_word32, context);
342 :
343 62 : Node* old_value_integer = ToInteger(context, old_value);
344 62 : Node* new_value_integer = ToInteger(context, new_value);
345 :
346 : #if DEBUG
347 : DebugSanityCheckAtomicIndex(array, index_word32, context);
348 : #endif
349 :
350 : #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || \
351 : V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
352 : Return(CallRuntime(Runtime::kAtomicsCompareExchange, context, array,
353 : index_integer, old_value_integer, new_value_integer));
354 : #else
355 31 : Node* index_word = ChangeUint32ToWord(index_word32);
356 :
357 31 : Node* old_value_word32 = TruncateTaggedToWord32(context, old_value_integer);
358 :
359 31 : Node* new_value_word32 = TruncateTaggedToWord32(context, new_value_integer);
360 :
361 31 : Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
362 31 : other(this);
363 : int32_t case_values[] = {
364 : FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE,
365 : FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE,
366 31 : };
367 : Label* case_labels[] = {
368 : &i8, &u8, &i16, &u16, &i32, &u32,
369 31 : };
370 : Switch(instance_type, &other, case_values, case_labels,
371 31 : arraysize(case_labels));
372 :
373 31 : BIND(&i8);
374 : Return(SmiFromWord32(AtomicCompareExchange(MachineType::Int8(), backing_store,
375 : index_word, old_value_word32,
376 93 : new_value_word32)));
377 :
378 31 : BIND(&u8);
379 : Return(SmiFromWord32(
380 : AtomicCompareExchange(MachineType::Uint8(), backing_store, index_word,
381 93 : old_value_word32, new_value_word32)));
382 :
383 31 : BIND(&i16);
384 : Return(SmiFromWord32(AtomicCompareExchange(
385 31 : MachineType::Int16(), backing_store, WordShl(index_word, 1),
386 124 : old_value_word32, new_value_word32)));
387 :
388 31 : BIND(&u16);
389 : Return(SmiFromWord32(AtomicCompareExchange(
390 31 : MachineType::Uint16(), backing_store, WordShl(index_word, 1),
391 124 : old_value_word32, new_value_word32)));
392 :
393 31 : BIND(&i32);
394 : Return(ChangeInt32ToTagged(AtomicCompareExchange(
395 31 : MachineType::Int32(), backing_store, WordShl(index_word, 2),
396 124 : old_value_word32, new_value_word32)));
397 :
398 31 : BIND(&u32);
399 : Return(ChangeUint32ToTagged(AtomicCompareExchange(
400 31 : MachineType::Uint32(), backing_store, WordShl(index_word, 2),
401 124 : old_value_word32, new_value_word32)));
402 :
403 : // This shouldn't happen, we've already validated the type.
404 31 : BIND(&other);
405 62 : Unreachable();
406 : #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64
407 : // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
408 31 : }
409 :
410 : #define BINOP_BUILTIN(op) \
411 : TF_BUILTIN(Atomics##op, SharedArrayBufferBuiltinsAssembler) { \
412 : Node* array = Parameter(Descriptor::kArray); \
413 : Node* index = Parameter(Descriptor::kIndex); \
414 : Node* value = Parameter(Descriptor::kValue); \
415 : Node* context = Parameter(Descriptor::kContext); \
416 : AtomicBinopBuiltinCommon(array, index, value, context, \
417 : &CodeAssembler::Atomic##op, \
418 : Runtime::kAtomics##op); \
419 : }
420 124 : BINOP_BUILTIN(Add)
421 124 : BINOP_BUILTIN(Sub)
422 124 : BINOP_BUILTIN(And)
423 124 : BINOP_BUILTIN(Or)
424 124 : BINOP_BUILTIN(Xor)
425 : #undef BINOP_BUILTIN
426 :
427 155 : void SharedArrayBufferBuiltinsAssembler::AtomicBinopBuiltinCommon(
428 : Node* array, Node* index, Node* value, Node* context,
429 : AssemblerFunction function, Runtime::FunctionId runtime_function) {
430 : Node* instance_type;
431 : Node* backing_store;
432 155 : ValidateSharedTypedArray(array, context, &instance_type, &backing_store);
433 :
434 : Node* index_integer;
435 : Node* index_word32 =
436 155 : ConvertTaggedAtomicIndexToWord32(index, context, &index_integer);
437 155 : ValidateAtomicIndex(array, index_word32, context);
438 :
439 310 : Node* value_integer = ToInteger(context, value);
440 :
441 : #if DEBUG
442 : // In Debug mode, we re-validate the index as a sanity check because
443 : // ToInteger above calls out to JavaScript. A SharedArrayBuffer can't be
444 : // neutered and the TypedArray length can't change either, so skipping this
445 : // check in Release mode is safe.
446 : ValidateAtomicIndex(array, index_word32, context);
447 : #endif
448 :
449 : #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || \
450 : V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
451 : Return(CallRuntime(runtime_function, context, array, index_integer,
452 : value_integer));
453 : #else
454 310 : Node* index_word = ChangeUint32ToWord(index_word32);
455 :
456 155 : Node* value_word32 = TruncateTaggedToWord32(context, value_integer);
457 :
458 155 : Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this),
459 155 : other(this);
460 : int32_t case_values[] = {
461 : FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE,
462 : FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE,
463 155 : };
464 : Label* case_labels[] = {
465 : &i8, &u8, &i16, &u16, &i32, &u32,
466 155 : };
467 : Switch(instance_type, &other, case_values, case_labels,
468 155 : arraysize(case_labels));
469 :
470 155 : BIND(&i8);
471 : Return(SmiFromWord32((this->*function)(MachineType::Int8(), backing_store,
472 465 : index_word, value_word32)));
473 :
474 155 : BIND(&u8);
475 : Return(SmiFromWord32((this->*function)(MachineType::Uint8(), backing_store,
476 465 : index_word, value_word32)));
477 :
478 155 : BIND(&i16);
479 : Return(
480 : SmiFromWord32((this->*function)(MachineType::Int16(), backing_store,
481 775 : WordShl(index_word, 1), value_word32)));
482 :
483 155 : BIND(&u16);
484 : Return(
485 : SmiFromWord32((this->*function)(MachineType::Uint16(), backing_store,
486 775 : WordShl(index_word, 1), value_word32)));
487 :
488 155 : BIND(&i32);
489 : Return(ChangeInt32ToTagged(
490 : (this->*function)(MachineType::Int32(), backing_store,
491 775 : WordShl(index_word, 2), value_word32)));
492 :
493 155 : BIND(&u32);
494 : Return(ChangeUint32ToTagged(
495 : (this->*function)(MachineType::Uint32(), backing_store,
496 775 : WordShl(index_word, 2), value_word32)));
497 :
498 : // This shouldn't happen, we've already validated the type.
499 155 : BIND(&other);
500 310 : Unreachable();
501 : #endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64
502 : // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
503 155 : }
504 :
505 : } // namespace internal
506 : } // namespace v8
|