blob: 5728e459b9ee8957fee7b075b8f78afda93035f4 [file] [log] [blame]
Ben Murdochda12d292016-06-02 14:46:10 +01001// 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/s390/codegen-s390.h"
6
7#if V8_TARGET_ARCH_S390
8
9#include "src/codegen.h"
10#include "src/macro-assembler.h"
11#include "src/s390/simulator-s390.h"
12
13namespace v8 {
14namespace internal {
15
16#define __ masm.
17
Ben Murdochda12d292016-06-02 14:46:10 +010018UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
19#if defined(USE_SIMULATOR)
20 return nullptr;
21#else
22 size_t actual_size;
23 byte* buffer =
24 static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
25 if (buffer == nullptr) return nullptr;
26
27 MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size),
28 CodeObjectRequired::kNo);
29
30 __ MovFromFloatParameter(d0);
31 __ sqdbr(d0, d0);
32 __ MovToFloatResult(d0);
33 __ Ret();
34
35 CodeDesc desc;
36 masm.GetCode(&desc);
37 DCHECK(ABI_USES_FUNCTION_DESCRIPTORS || !RelocInfo::RequiresRelocation(desc));
38
39 Assembler::FlushICache(isolate, buffer, actual_size);
40 base::OS::ProtectCode(buffer, actual_size);
41 return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
42#endif
43}
44
45#undef __
46
47// -------------------------------------------------------------------------
48// Platform-specific RuntimeCallHelper functions.
49
50void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
51 masm->EnterFrame(StackFrame::INTERNAL);
52 DCHECK(!masm->has_frame());
53 masm->set_has_frame(true);
54}
55
56void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
57 masm->LeaveFrame(StackFrame::INTERNAL);
58 DCHECK(masm->has_frame());
59 masm->set_has_frame(false);
60}
61
62// -------------------------------------------------------------------------
63// Code generators
64
65#define __ ACCESS_MASM(masm)
66
67void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
68 MacroAssembler* masm, Register receiver, Register key, Register value,
69 Register target_map, AllocationSiteMode mode,
70 Label* allocation_memento_found) {
71 Register scratch_elements = r6;
72 DCHECK(!AreAliased(receiver, key, value, target_map, scratch_elements));
73
74 if (mode == TRACK_ALLOCATION_SITE) {
75 DCHECK(allocation_memento_found != NULL);
76 __ JumpIfJSArrayHasAllocationMemento(receiver, scratch_elements, r1,
77 allocation_memento_found);
78 }
79
80 // Set transitioned map.
81 __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
82 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, r1,
83 kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
84 OMIT_SMI_CHECK);
85}
86
87void ElementsTransitionGenerator::GenerateSmiToDouble(
88 MacroAssembler* masm, Register receiver, Register key, Register value,
89 Register target_map, AllocationSiteMode mode, Label* fail) {
90 // lr contains the return address
91 Label loop, entry, convert_hole, gc_required, only_change_map, done;
92 Register elements = r6;
93 Register length = r7;
94 Register array = r8;
95 Register array_end = array;
96
97 // target_map parameter can be clobbered.
98 Register scratch1 = target_map;
99 Register scratch2 = r1;
100
101 // Verify input registers don't conflict with locals.
102 DCHECK(!AreAliased(receiver, key, value, target_map, elements, length, array,
103 scratch2));
104
105 if (mode == TRACK_ALLOCATION_SITE) {
106 __ JumpIfJSArrayHasAllocationMemento(receiver, elements, scratch2, fail);
107 }
108
109 // Check for empty arrays, which only require a map transition and no changes
110 // to the backing store.
111 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
112 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
113 __ beq(&only_change_map, Label::kNear);
114
115 // Preserve lr and use r14 as a temporary register.
116 __ push(r14);
117
118 __ LoadP(length, FieldMemOperand(elements, FixedArray::kLengthOffset));
119 // length: number of elements (smi-tagged)
120
121 // Allocate new FixedDoubleArray.
122 __ SmiToDoubleArrayOffset(r14, length);
123 __ AddP(r14, Operand(FixedDoubleArray::kHeaderSize));
124 __ Allocate(r14, array, r9, scratch2, &gc_required, DOUBLE_ALIGNMENT);
Ben Murdochc5610432016-08-08 18:44:38 +0100125 __ SubP(array, array, Operand(kHeapObjectTag));
Ben Murdochda12d292016-06-02 14:46:10 +0100126 // Set destination FixedDoubleArray's length and map.
127 __ LoadRoot(scratch2, Heap::kFixedDoubleArrayMapRootIndex);
128 __ StoreP(length, MemOperand(array, FixedDoubleArray::kLengthOffset));
129 // Update receiver's map.
130 __ StoreP(scratch2, MemOperand(array, HeapObject::kMapOffset));
131
132 __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
133 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch2,
134 kLRHasBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
135 OMIT_SMI_CHECK);
136 // Replace receiver's backing store with newly created FixedDoubleArray.
137 __ AddP(scratch1, array, Operand(kHeapObjectTag));
138 __ StoreP(scratch1, FieldMemOperand(receiver, JSObject::kElementsOffset));
139 __ RecordWriteField(receiver, JSObject::kElementsOffset, scratch1, scratch2,
140 kLRHasBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
141 OMIT_SMI_CHECK);
142
143 // Prepare for conversion loop.
144 __ AddP(target_map, elements,
145 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
146 __ AddP(r9, array, Operand(FixedDoubleArray::kHeaderSize));
147 __ SmiToDoubleArrayOffset(array, length);
148 __ AddP(array_end, r9, array);
149// Repurpose registers no longer in use.
150#if V8_TARGET_ARCH_S390X
151 Register hole_int64 = elements;
152#else
153 Register hole_lower = elements;
154 Register hole_upper = length;
155#endif
156 // scratch1: begin of source FixedArray element fields, not tagged
157 // hole_lower: kHoleNanLower32 OR hol_int64
158 // hole_upper: kHoleNanUpper32
159 // array_end: end of destination FixedDoubleArray, not tagged
160 // scratch2: begin of FixedDoubleArray element fields, not tagged
161
162 __ b(&entry, Label::kNear);
163
164 __ bind(&only_change_map);
165 __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
166 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch2,
167 kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
168 OMIT_SMI_CHECK);
169 __ b(&done, Label::kNear);
170
171 // Call into runtime if GC is required.
172 __ bind(&gc_required);
173 __ pop(r14);
174 __ b(fail);
175
176 // Convert and copy elements.
177 __ bind(&loop);
178 __ LoadP(r14, MemOperand(scratch1));
179 __ la(scratch1, MemOperand(scratch1, kPointerSize));
180 // r1: current element
181 __ UntagAndJumpIfNotSmi(r14, r14, &convert_hole);
182
183 // Normal smi, convert to double and store.
184 __ ConvertIntToDouble(r14, d0);
185 __ StoreDouble(d0, MemOperand(r9, 0));
186 __ la(r9, MemOperand(r9, 8));
187
188 __ b(&entry, Label::kNear);
189
190 // Hole found, store the-hole NaN.
191 __ bind(&convert_hole);
192 if (FLAG_debug_code) {
193 // Restore a "smi-untagged" heap object.
194 __ LoadP(r1, MemOperand(r5, -kPointerSize));
195 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
196 __ Assert(eq, kObjectFoundInSmiOnlyArray);
197 }
198#if V8_TARGET_ARCH_S390X
199 __ stg(hole_int64, MemOperand(r9, 0));
200#else
201 __ StoreW(hole_upper, MemOperand(r9, Register::kExponentOffset));
202 __ StoreW(hole_lower, MemOperand(r9, Register::kMantissaOffset));
203#endif
204 __ AddP(r9, Operand(8));
205
206 __ bind(&entry);
207 __ CmpP(r9, array_end);
208 __ blt(&loop);
209
210 __ pop(r14);
211 __ bind(&done);
212}
213
214void ElementsTransitionGenerator::GenerateDoubleToObject(
215 MacroAssembler* masm, Register receiver, Register key, Register value,
216 Register target_map, AllocationSiteMode mode, Label* fail) {
217 // Register lr contains the return address.
218 Label loop, convert_hole, gc_required, only_change_map;
219 Register elements = r6;
220 Register array = r8;
221 Register length = r7;
222 Register scratch = r1;
223 Register scratch3 = r9;
224 Register hole_value = r9;
225
226 // Verify input registers don't conflict with locals.
227 DCHECK(!AreAliased(receiver, key, value, target_map, elements, array, length,
228 scratch));
229
230 if (mode == TRACK_ALLOCATION_SITE) {
231 __ JumpIfJSArrayHasAllocationMemento(receiver, elements, scratch3, fail);
232 }
233
234 // Check for empty arrays, which only require a map transition and no changes
235 // to the backing store.
236 __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
237 __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
238 __ beq(&only_change_map);
239
240 __ Push(target_map, receiver, key, value);
241 __ LoadP(length, FieldMemOperand(elements, FixedArray::kLengthOffset));
242 // elements: source FixedDoubleArray
243 // length: number of elements (smi-tagged)
244
245 // Allocate new FixedArray.
246 // Re-use value and target_map registers, as they have been saved on the
247 // stack.
248 Register array_size = value;
249 Register allocate_scratch = target_map;
250 __ LoadImmP(array_size, Operand(FixedDoubleArray::kHeaderSize));
251 __ SmiToPtrArrayOffset(r0, length);
252 __ AddP(array_size, r0);
253 __ Allocate(array_size, array, allocate_scratch, scratch, &gc_required,
254 NO_ALLOCATION_FLAGS);
Ben Murdochc5610432016-08-08 18:44:38 +0100255 // array: destination FixedArray, tagged as heap object
Ben Murdochda12d292016-06-02 14:46:10 +0100256 // Set destination FixedDoubleArray's length and map.
257 __ LoadRoot(scratch, Heap::kFixedArrayMapRootIndex);
Ben Murdochc5610432016-08-08 18:44:38 +0100258 __ StoreP(length, FieldMemOperand(array, FixedDoubleArray::kLengthOffset),
259 r0);
260 __ StoreP(scratch, FieldMemOperand(array, HeapObject::kMapOffset), r0);
Ben Murdochda12d292016-06-02 14:46:10 +0100261
262 // Prepare for conversion loop.
263 Register src_elements = elements;
264 Register dst_elements = target_map;
265 Register dst_end = length;
266 Register heap_number_map = scratch;
267 __ AddP(src_elements,
268 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
269 __ SmiToPtrArrayOffset(length, length);
270 __ LoadRoot(hole_value, Heap::kTheHoleValueRootIndex);
271
272 Label initialization_loop, loop_done;
273 __ ShiftRightP(scratch, length, Operand(kPointerSizeLog2));
274 __ beq(&loop_done, Label::kNear);
275
276 // Allocating heap numbers in the loop below can fail and cause a jump to
277 // gc_required. We can't leave a partly initialized FixedArray behind,
278 // so pessimistically fill it with holes now.
279 __ AddP(dst_elements, array,
280 Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize));
281 __ bind(&initialization_loop);
282 __ StoreP(hole_value, MemOperand(dst_elements, kPointerSize));
283 __ lay(dst_elements, MemOperand(dst_elements, kPointerSize));
284 __ BranchOnCount(scratch, &initialization_loop);
285
286 __ AddP(dst_elements, array,
287 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
288 __ AddP(dst_end, dst_elements, length);
289 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
290 // Using offsetted addresses in src_elements to fully take advantage of
291 // post-indexing.
292 // dst_elements: begin of destination FixedArray element fields, not tagged
293 // src_elements: begin of source FixedDoubleArray element fields,
294 // not tagged, +4
295 // dst_end: end of destination FixedArray, not tagged
296 // array: destination FixedArray
297 // hole_value: the-hole pointer
298 // heap_number_map: heap number map
299 __ b(&loop, Label::kNear);
300
301 // Call into runtime if GC is required.
302 __ bind(&gc_required);
303 __ Pop(target_map, receiver, key, value);
304 __ b(fail);
305
306 // Replace the-hole NaN with the-hole pointer.
307 __ bind(&convert_hole);
308 __ StoreP(hole_value, MemOperand(dst_elements));
309 __ AddP(dst_elements, Operand(kPointerSize));
310 __ CmpLogicalP(dst_elements, dst_end);
311 __ bge(&loop_done);
312
313 __ bind(&loop);
314 Register upper_bits = key;
315 __ LoadlW(upper_bits, MemOperand(src_elements, Register::kExponentOffset));
316 __ AddP(src_elements, Operand(kDoubleSize));
317 // upper_bits: current element's upper 32 bit
318 // src_elements: address of next element's upper 32 bit
319 __ Cmp32(upper_bits, Operand(kHoleNanUpper32));
320 __ beq(&convert_hole, Label::kNear);
321
322 // Non-hole double, copy value into a heap number.
323 Register heap_number = receiver;
324 Register scratch2 = value;
325 __ AllocateHeapNumber(heap_number, scratch2, scratch3, heap_number_map,
326 &gc_required);
327// heap_number: new heap number
328#if V8_TARGET_ARCH_S390X
329 __ lg(scratch2, MemOperand(src_elements, -kDoubleSize));
330 // subtract tag for std
331 __ AddP(upper_bits, heap_number, Operand(-kHeapObjectTag));
332 __ stg(scratch2, MemOperand(upper_bits, HeapNumber::kValueOffset));
333#else
334 __ LoadlW(scratch2,
335 MemOperand(src_elements, Register::kMantissaOffset - kDoubleSize));
336 __ LoadlW(upper_bits,
337 MemOperand(src_elements, Register::kExponentOffset - kDoubleSize));
338 __ StoreW(scratch2,
339 FieldMemOperand(heap_number, HeapNumber::kMantissaOffset));
340 __ StoreW(upper_bits,
341 FieldMemOperand(heap_number, HeapNumber::kExponentOffset));
342#endif
343 __ LoadRR(scratch2, dst_elements);
344 __ StoreP(heap_number, MemOperand(dst_elements));
345 __ AddP(dst_elements, Operand(kPointerSize));
346 __ RecordWrite(array, scratch2, heap_number, kLRHasNotBeenSaved,
347 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
348 __ CmpLogicalP(dst_elements, dst_end);
349 __ blt(&loop);
350 __ bind(&loop_done);
351
352 __ Pop(target_map, receiver, key, value);
353 // Replace receiver's backing store with newly created and filled FixedArray.
354 __ StoreP(array, FieldMemOperand(receiver, JSObject::kElementsOffset));
355 __ RecordWriteField(receiver, JSObject::kElementsOffset, array, scratch,
356 kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
357 OMIT_SMI_CHECK);
358
359 __ bind(&only_change_map);
360 // Update receiver's map.
361 __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
362 __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch,
363 kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
364 OMIT_SMI_CHECK);
365}
366
367// assume ip can be used as a scratch register below
368void StringCharLoadGenerator::Generate(MacroAssembler* masm, Register string,
369 Register index, Register result,
370 Label* call_runtime) {
371 // Fetch the instance type of the receiver into result register.
372 __ LoadP(result, FieldMemOperand(string, HeapObject::kMapOffset));
373 __ LoadlB(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
374
375 // We need special handling for indirect strings.
376 Label check_sequential;
377 __ mov(r0, Operand(kIsIndirectStringMask));
378 __ AndP(r0, result);
379 __ beq(&check_sequential, Label::kNear /*, cr0*/);
380
381 // Dispatch on the indirect string shape: slice or cons.
382 Label cons_string;
383 __ mov(ip, Operand(kSlicedNotConsMask));
384 __ LoadRR(r0, result);
385 __ AndP(r0, ip /*, SetRC*/); // Should be okay to remove RC
386 __ beq(&cons_string, Label::kNear /*, cr0*/);
387
388 // Handle slices.
389 Label indirect_string_loaded;
390 __ LoadP(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
391 __ LoadP(string, FieldMemOperand(string, SlicedString::kParentOffset));
392 __ SmiUntag(ip, result);
393 __ AddP(index, ip);
394 __ b(&indirect_string_loaded, Label::kNear);
395
396 // Handle cons strings.
397 // Check whether the right hand side is the empty string (i.e. if
398 // this is really a flat string in a cons string). If that is not
399 // the case we would rather go to the runtime system now to flatten
400 // the string.
401 __ bind(&cons_string);
402 __ LoadP(result, FieldMemOperand(string, ConsString::kSecondOffset));
403 __ CompareRoot(result, Heap::kempty_stringRootIndex);
404 __ bne(call_runtime);
405 // Get the first of the two strings and load its instance type.
406 __ LoadP(string, FieldMemOperand(string, ConsString::kFirstOffset));
407
408 __ bind(&indirect_string_loaded);
409 __ LoadP(result, FieldMemOperand(string, HeapObject::kMapOffset));
410 __ LoadlB(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
411
412 // Distinguish sequential and external strings. Only these two string
413 // representations can reach here (slices and flat cons strings have been
414 // reduced to the underlying sequential or external string).
415 Label external_string, check_encoding;
416 __ bind(&check_sequential);
417 STATIC_ASSERT(kSeqStringTag == 0);
418 __ mov(r0, Operand(kStringRepresentationMask));
419 __ AndP(r0, result);
420 __ bne(&external_string, Label::kNear);
421
422 // Prepare sequential strings
423 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
424 __ AddP(string, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
425 __ b(&check_encoding, Label::kNear);
426
427 // Handle external strings.
428 __ bind(&external_string);
429 if (FLAG_debug_code) {
430 // Assert that we do not have a cons or slice (indirect strings) here.
431 // Sequential strings have already been ruled out.
432 __ mov(r0, Operand(kIsIndirectStringMask));
433 __ AndP(r0, result);
434 __ Assert(eq, kExternalStringExpectedButNotFound, cr0);
435 }
436 // Rule out short external strings.
437 STATIC_ASSERT(kShortExternalStringTag != 0);
438 __ mov(r0, Operand(kShortExternalStringMask));
439 __ AndP(r0, result);
440 __ bne(call_runtime /*, cr0*/);
441 __ LoadP(string,
442 FieldMemOperand(string, ExternalString::kResourceDataOffset));
443
444 Label one_byte, done;
445 __ bind(&check_encoding);
446 STATIC_ASSERT(kTwoByteStringTag == 0);
447 __ mov(r0, Operand(kStringEncodingMask));
448 __ AndP(r0, result);
449 __ bne(&one_byte, Label::kNear);
450 // Two-byte string.
451 __ ShiftLeftP(result, index, Operand(1));
452 __ LoadLogicalHalfWordP(result, MemOperand(string, result));
453 __ b(&done, Label::kNear);
454 __ bind(&one_byte);
455 // One-byte string.
456 __ LoadlB(result, MemOperand(string, index));
457 __ bind(&done);
458}
459
Ben Murdochda12d292016-06-02 14:46:10 +0100460#undef __
461
462CodeAgingHelper::CodeAgingHelper(Isolate* isolate) {
463 USE(isolate);
464 DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength);
465 // Since patcher is a large object, allocate it dynamically when needed,
466 // to avoid overloading the stack in stress conditions.
467 // DONT_FLUSH is used because the CodeAgingHelper is initialized early in
468 // the process, before ARM simulator ICache is setup.
469 base::SmartPointer<CodePatcher> patcher(
470 new CodePatcher(isolate, young_sequence_.start(),
471 young_sequence_.length(), CodePatcher::DONT_FLUSH));
472 PredictableCodeSizeScope scope(patcher->masm(), young_sequence_.length());
473 patcher->masm()->PushStandardFrame(r3);
474}
475
476#ifdef DEBUG
477bool CodeAgingHelper::IsOld(byte* candidate) const {
478 return Assembler::IsNop(Assembler::instr_at(candidate));
479}
480#endif
481
482bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
483 bool result = isolate->code_aging_helper()->IsYoung(sequence);
484 DCHECK(result || isolate->code_aging_helper()->IsOld(sequence));
485 return result;
486}
487
488void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
489 MarkingParity* parity) {
490 if (IsYoungSequence(isolate, sequence)) {
491 *age = kNoAgeCodeAge;
492 *parity = NO_MARKING_PARITY;
493 } else {
494 Code* code = NULL;
495 Address target_address =
496 Assembler::target_address_at(sequence + kCodeAgingTargetDelta, code);
497 Code* stub = GetCodeFromTargetAddress(target_address);
498 GetCodeAgeAndParity(stub, age, parity);
499 }
500}
501
502void Code::PatchPlatformCodeAge(Isolate* isolate, byte* sequence, Code::Age age,
503 MarkingParity parity) {
504 uint32_t young_length = isolate->code_aging_helper()->young_sequence_length();
505 if (age == kNoAgeCodeAge) {
506 isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
507 Assembler::FlushICache(isolate, sequence, young_length);
508 } else {
509 // FIXED_SEQUENCE
510 Code* stub = GetCodeAgeStub(isolate, age, parity);
511 CodePatcher patcher(isolate, sequence, young_length);
512 intptr_t target = reinterpret_cast<intptr_t>(stub->instruction_start());
513 // We need to push lr on stack so that GenerateMakeCodeYoungAgainCommon
514 // knows where to pick up the return address
515 //
516 // Since we can no longer guarentee ip will hold the branch address
517 // because of BRASL, use Call so that GenerateMakeCodeYoungAgainCommon
518 // can calculate the branch address offset
519 patcher.masm()->nop(); // marker to detect sequence (see IsOld)
520 patcher.masm()->CleanseP(r14);
521 patcher.masm()->Push(r14);
522 patcher.masm()->mov(r2, Operand(target));
523 patcher.masm()->Call(r2);
524 for (int i = 0; i < kNoCodeAgeSequenceLength - kCodeAgingSequenceLength;
525 i += 2) {
526 // TODO(joransiu): Create nop function to pad
527 // (kNoCodeAgeSequenceLength - kCodeAgingSequenceLength) bytes.
528 patcher.masm()->nop(); // 2-byte nops().
529 }
530 }
531}
532
533} // namespace internal
534} // namespace v8
535
536#endif // V8_TARGET_ARCH_S390