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

Side by Side Diff: src/full-codegen/arm/full-codegen-arm.cc

Issue 1708523002: [fullcodegen] Remove the hacky %_FastOneByteArrayJoin intrinsic. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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/crankshaft/hydrogen.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 #if V8_TARGET_ARCH_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 3418 matching lines...) Expand 10 before | Expand all | Expand 10 after
3429 ZoneList<Expression*>* args = expr->arguments(); 3429 ZoneList<Expression*>* args = expr->arguments();
3430 DCHECK_EQ(1, args->length()); 3430 DCHECK_EQ(1, args->length());
3431 VisitForAccumulatorValue(args->at(0)); 3431 VisitForAccumulatorValue(args->at(0));
3432 __ AssertFunction(r0); 3432 __ AssertFunction(r0);
3433 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); 3433 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
3434 __ ldr(r0, FieldMemOperand(r0, Map::kPrototypeOffset)); 3434 __ ldr(r0, FieldMemOperand(r0, Map::kPrototypeOffset));
3435 context()->Plug(r0); 3435 context()->Plug(r0);
3436 } 3436 }
3437 3437
3438 3438
3439 void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) {
3440 Label bailout, done, one_char_separator, long_separator, non_trivial_array,
3441 not_size_one_array, loop, empty_separator_loop, one_char_separator_loop,
3442 one_char_separator_loop_entry, long_separator_loop;
3443 ZoneList<Expression*>* args = expr->arguments();
3444 DCHECK(args->length() == 2);
3445 VisitForStackValue(args->at(1));
3446 VisitForAccumulatorValue(args->at(0));
3447
3448 // All aliases of the same register have disjoint lifetimes.
3449 Register array = r0;
3450 Register elements = no_reg; // Will be r0.
3451 Register result = no_reg; // Will be r0.
3452 Register separator = r1;
3453 Register array_length = r2;
3454 Register result_pos = no_reg; // Will be r2
3455 Register string_length = r3;
3456 Register string = r4;
3457 Register element = r5;
3458 Register elements_end = r6;
3459 Register scratch = r9;
3460
3461 // Separator operand is on the stack.
3462 __ pop(separator);
3463
3464 // Check that the array is a JSArray.
3465 __ JumpIfSmi(array, &bailout);
3466 __ CompareObjectType(array, scratch, array_length, JS_ARRAY_TYPE);
3467 __ b(ne, &bailout);
3468
3469 // Check that the array has fast elements.
3470 __ CheckFastElements(scratch, array_length, &bailout);
3471
3472 // If the array has length zero, return the empty string.
3473 __ ldr(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
3474 __ SmiUntag(array_length, SetCC);
3475 __ b(ne, &non_trivial_array);
3476 __ LoadRoot(r0, Heap::kempty_stringRootIndex);
3477 __ b(&done);
3478
3479 __ bind(&non_trivial_array);
3480
3481 // Get the FixedArray containing array's elements.
3482 elements = array;
3483 __ ldr(elements, FieldMemOperand(array, JSArray::kElementsOffset));
3484 array = no_reg; // End of array's live range.
3485
3486 // Check that all array elements are sequential one-byte strings, and
3487 // accumulate the sum of their lengths, as a smi-encoded value.
3488 __ mov(string_length, Operand::Zero());
3489 __ add(element,
3490 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3491 __ add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
3492 // Loop condition: while (element < elements_end).
3493 // Live values in registers:
3494 // elements: Fixed array of strings.
3495 // array_length: Length of the fixed array of strings (not smi)
3496 // separator: Separator string
3497 // string_length: Accumulated sum of string lengths (smi).
3498 // element: Current array element.
3499 // elements_end: Array end.
3500 if (generate_debug_code_) {
3501 __ cmp(array_length, Operand::Zero());
3502 __ Assert(gt, kNoEmptyArraysHereInEmitFastOneByteArrayJoin);
3503 }
3504 __ bind(&loop);
3505 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
3506 __ JumpIfSmi(string, &bailout);
3507 __ ldr(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
3508 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
3509 __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch, scratch, &bailout);
3510 __ ldr(scratch, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
3511 __ add(string_length, string_length, Operand(scratch), SetCC);
3512 __ b(vs, &bailout);
3513 __ cmp(element, elements_end);
3514 __ b(lt, &loop);
3515
3516 // If array_length is 1, return elements[0], a string.
3517 __ cmp(array_length, Operand(1));
3518 __ b(ne, &not_size_one_array);
3519 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize));
3520 __ b(&done);
3521
3522 __ bind(&not_size_one_array);
3523
3524 // Live values in registers:
3525 // separator: Separator string
3526 // array_length: Length of the array.
3527 // string_length: Sum of string lengths (smi).
3528 // elements: FixedArray of strings.
3529
3530 // Check that the separator is a flat one-byte string.
3531 __ JumpIfSmi(separator, &bailout);
3532 __ ldr(scratch, FieldMemOperand(separator, HeapObject::kMapOffset));
3533 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
3534 __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch, scratch, &bailout);
3535
3536 // Add (separator length times array_length) - separator length to the
3537 // string_length to get the length of the result string. array_length is not
3538 // smi but the other values are, so the result is a smi
3539 __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
3540 __ sub(string_length, string_length, Operand(scratch));
3541 __ smull(scratch, ip, array_length, scratch);
3542 // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
3543 // zero.
3544 __ cmp(ip, Operand::Zero());
3545 __ b(ne, &bailout);
3546 __ tst(scratch, Operand(0x80000000));
3547 __ b(ne, &bailout);
3548 __ add(string_length, string_length, Operand(scratch), SetCC);
3549 __ b(vs, &bailout);
3550 __ SmiUntag(string_length);
3551
3552 // Bailout for large object allocations.
3553 __ cmp(string_length, Operand(Page::kMaxRegularHeapObjectSize));
3554 __ b(gt, &bailout);
3555
3556 // Get first element in the array to free up the elements register to be used
3557 // for the result.
3558 __ add(element,
3559 elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3560 result = elements; // End of live range for elements.
3561 elements = no_reg;
3562 // Live values in registers:
3563 // element: First array element
3564 // separator: Separator string
3565 // string_length: Length of result string (not smi)
3566 // array_length: Length of the array.
3567 __ AllocateOneByteString(result, string_length, scratch,
3568 string, // used as scratch
3569 elements_end, // used as scratch
3570 &bailout);
3571 // Prepare for looping. Set up elements_end to end of the array. Set
3572 // result_pos to the position of the result where to write the first
3573 // character.
3574 __ add(elements_end, element, Operand(array_length, LSL, kPointerSizeLog2));
3575 result_pos = array_length; // End of live range for array_length.
3576 array_length = no_reg;
3577 __ add(result_pos,
3578 result,
3579 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3580
3581 // Check the length of the separator.
3582 __ ldr(scratch, FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
3583 __ cmp(scratch, Operand(Smi::FromInt(1)));
3584 __ b(eq, &one_char_separator);
3585 __ b(gt, &long_separator);
3586
3587 // Empty separator case
3588 __ bind(&empty_separator_loop);
3589 // Live values in registers:
3590 // result_pos: the position to which we are currently copying characters.
3591 // element: Current array element.
3592 // elements_end: Array end.
3593
3594 // Copy next array element to the result.
3595 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
3596 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
3597 __ SmiUntag(string_length);
3598 __ add(string,
3599 string,
3600 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3601 __ CopyBytes(string, result_pos, string_length, scratch);
3602 __ cmp(element, elements_end);
3603 __ b(lt, &empty_separator_loop); // End while (element < elements_end).
3604 DCHECK(result.is(r0));
3605 __ b(&done);
3606
3607 // One-character separator case
3608 __ bind(&one_char_separator);
3609 // Replace separator with its one-byte character value.
3610 __ ldrb(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
3611 // Jump into the loop after the code that copies the separator, so the first
3612 // element is not preceded by a separator
3613 __ jmp(&one_char_separator_loop_entry);
3614
3615 __ bind(&one_char_separator_loop);
3616 // Live values in registers:
3617 // result_pos: the position to which we are currently copying characters.
3618 // element: Current array element.
3619 // elements_end: Array end.
3620 // separator: Single separator one-byte char (in lower byte).
3621
3622 // Copy the separator character to the result.
3623 __ strb(separator, MemOperand(result_pos, 1, PostIndex));
3624
3625 // Copy next array element to the result.
3626 __ bind(&one_char_separator_loop_entry);
3627 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
3628 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
3629 __ SmiUntag(string_length);
3630 __ add(string,
3631 string,
3632 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3633 __ CopyBytes(string, result_pos, string_length, scratch);
3634 __ cmp(element, elements_end);
3635 __ b(lt, &one_char_separator_loop); // End while (element < elements_end).
3636 DCHECK(result.is(r0));
3637 __ b(&done);
3638
3639 // Long separator case (separator is more than one character). Entry is at the
3640 // label long_separator below.
3641 __ bind(&long_separator_loop);
3642 // Live values in registers:
3643 // result_pos: the position to which we are currently copying characters.
3644 // element: Current array element.
3645 // elements_end: Array end.
3646 // separator: Separator string.
3647
3648 // Copy the separator to the result.
3649 __ ldr(string_length, FieldMemOperand(separator, String::kLengthOffset));
3650 __ SmiUntag(string_length);
3651 __ add(string,
3652 separator,
3653 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3654 __ CopyBytes(string, result_pos, string_length, scratch);
3655
3656 __ bind(&long_separator);
3657 __ ldr(string, MemOperand(element, kPointerSize, PostIndex));
3658 __ ldr(string_length, FieldMemOperand(string, String::kLengthOffset));
3659 __ SmiUntag(string_length);
3660 __ add(string,
3661 string,
3662 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3663 __ CopyBytes(string, result_pos, string_length, scratch);
3664 __ cmp(element, elements_end);
3665 __ b(lt, &long_separator_loop); // End while (element < elements_end).
3666 DCHECK(result.is(r0));
3667 __ b(&done);
3668
3669 __ bind(&bailout);
3670 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
3671 __ bind(&done);
3672 context()->Plug(r0);
3673 }
3674
3675
3676 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { 3439 void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
3677 DCHECK(expr->arguments()->length() == 0); 3440 DCHECK(expr->arguments()->length() == 0);
3678 ExternalReference debug_is_active = 3441 ExternalReference debug_is_active =
3679 ExternalReference::debug_is_active_address(isolate()); 3442 ExternalReference::debug_is_active_address(isolate());
3680 __ mov(ip, Operand(debug_is_active)); 3443 __ mov(ip, Operand(debug_is_active));
3681 __ ldrb(r0, MemOperand(ip)); 3444 __ ldrb(r0, MemOperand(ip));
3682 __ SmiTag(r0); 3445 __ SmiTag(r0);
3683 context()->Plug(r0); 3446 context()->Plug(r0);
3684 } 3447 }
3685 3448
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after
4586 DCHECK(interrupt_address == 4349 DCHECK(interrupt_address ==
4587 isolate->builtins()->OsrAfterStackCheck()->entry()); 4350 isolate->builtins()->OsrAfterStackCheck()->entry());
4588 return OSR_AFTER_STACK_CHECK; 4351 return OSR_AFTER_STACK_CHECK;
4589 } 4352 }
4590 4353
4591 4354
4592 } // namespace internal 4355 } // namespace internal
4593 } // namespace v8 4356 } // namespace v8
4594 4357
4595 #endif // V8_TARGET_ARCH_ARM 4358 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/crankshaft/hydrogen.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698