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

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

Issue 6148007: Speed up FastAsciiArrayJoin on ia32 by improving hand-written assembly code. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3333 matching lines...) Expand 10 before | Expand all | Expand 10 after
3344 } 3344 }
3345 3345
3346 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); 3346 __ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
3347 __ IndexFromHash(eax, eax); 3347 __ IndexFromHash(eax, eax);
3348 3348
3349 context()->Plug(eax); 3349 context()->Plug(eax);
3350 } 3350 }
3351 3351
3352 3352
3353 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) { 3353 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) {
3354 Label bailout; 3354 Label bailout, done, one_char_separator, long_separator,
3355 Label done; 3355 non_trivial_array, not_size_one_array, loop, loop_condition,
3356 loop_1, loop_1_condition, loop_1a, loop_1a_condition,
3357 loop_2, loop_2_entry, loop_2a, loop_2a_condition,
3358 loop_3, loop_3_entry, loop_3a, loop_3a_condition,
3359 loop_3b, loop_3b_condition;
Lasse Reichstein 2011/01/13 09:20:32 That's a lot of loops. Could they be given more te
William Hesse 2011/01/13 16:25:59 Loops eliminated by making the string copy a macro
3356 3360
3357 ASSERT(args->length() == 2); 3361 ASSERT(args->length() == 2);
3358 // We will leave the separator on the stack until the end of the function. 3362 // We will leave the separator on the stack until the end of the function.
3359 VisitForStackValue(args->at(1)); 3363 VisitForStackValue(args->at(1));
3360 // Load this to eax (= array) 3364 // Load this to eax (= array)
3361 VisitForAccumulatorValue(args->at(0)); 3365 VisitForAccumulatorValue(args->at(0));
3362 3366
3363 // All aliases of the same register have disjoint lifetimes. 3367 // All aliases of the same register have disjoint lifetimes.
3364 Register array = eax; 3368 Register array = eax;
3365 Register result_pos = no_reg; 3369 Register elements = no_reg; // Will be eax.
3370 Register result_pos = no_reg; // Will be eax.
3366 3371
3367 Register index = edi; 3372 Register index = edi;
3368 3373
3369 Register current_string_length = ecx; // Will be ecx when live. 3374 Register current_string_length = ecx;
3370 3375
3371 Register current_string = edx; 3376 Register current_string = edx;
3372 3377
3373 Register scratch = ebx; 3378 Register scratch = ebx;
3374 3379
3375 Register scratch_2 = esi; 3380 Register array_length = esi;
3376 Register new_padding_chars = scratch_2; 3381 Register pos = no_reg; // Will be esi.
3377 3382
3378 Operand separator = Operand(esp, 4 * kPointerSize); // Already pushed. 3383 // Separator operand is already pushed.
3379 Operand elements = Operand(esp, 3 * kPointerSize); 3384 Operand separator_operand = Operand(esp, 3 * kPointerSize);
3380 Operand result = Operand(esp, 2 * kPointerSize); 3385 Operand elements_operand = Operand(esp, 2 * kPointerSize);
3381 Operand padding_chars = Operand(esp, 1 * kPointerSize); 3386 Operand result_operand = Operand(esp, 1 * kPointerSize);
3382 Operand array_length = Operand(esp, 0); 3387 Operand array_length_operand = Operand(esp, 0);
3383 __ sub(Operand(esp), Immediate(4 * kPointerSize)); 3388 __ sub(Operand(esp), Immediate(3 * kPointerSize));
3384 3389
3385 3390 // Check that the array is a JSArray
3386 // Check that eax is a JSArray
3387 __ test(array, Immediate(kSmiTagMask)); 3391 __ test(array, Immediate(kSmiTagMask));
3388 __ j(zero, &bailout); 3392 __ j(zero, &bailout);
3389 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); 3393 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch);
3390 __ j(not_equal, &bailout); 3394 __ j(not_equal, &bailout);
3391 3395
3392 // Check that the array has fast elements. 3396 // Check that the array has fast elements.
3393 __ test_b(FieldOperand(scratch, Map::kBitField2Offset), 3397 __ test_b(FieldOperand(scratch, Map::kBitField2Offset),
3394 1 << Map::kHasFastElements); 3398 1 << Map::kHasFastElements);
Lasse Reichstein 2011/01/13 09:20:32 Will Copy-on-Write arrays have fast elements if qu
William Hesse 2011/01/13 16:25:59 Yes, they will (I checked).
3395 __ j(zero, &bailout); 3399 __ j(zero, &bailout);
3396 3400
3397 // If the array is empty, return the empty string. 3401 // If the array has length zero, return the empty string.
3398 __ mov(scratch, FieldOperand(array, JSArray::kLengthOffset)); 3402 __ mov(scratch, FieldOperand(array, JSArray::kLengthOffset));
3399 __ sar(scratch, 1); 3403 __ sar(scratch, 1);
3400 Label non_trivial; 3404 __ j(not_zero, &non_trivial_array);
3401 __ j(not_zero, &non_trivial); 3405 __ mov(result_operand, Factory::empty_string());
3402 __ mov(result, Factory::empty_string());
3403 __ jmp(&done); 3406 __ jmp(&done);
3404 3407
3405 __ bind(&non_trivial); 3408 // Save the array length.
3409 __ bind(&non_trivial_array);
3410 __ mov(array_length_operand, scratch);
3406 __ mov(array_length, scratch); 3411 __ mov(array_length, scratch);
3407 3412
3413 // Save the FixedArray containing array's elements.
3408 __ mov(scratch, FieldOperand(array, JSArray::kElementsOffset)); 3414 __ mov(scratch, FieldOperand(array, JSArray::kElementsOffset));
3415 // End of array's live range.
3416 elements = array;
3417 array = no_reg;
3418 __ mov(elements_operand, scratch);
3409 __ mov(elements, scratch); 3419 __ mov(elements, scratch);
3410 3420
3411 // End of array's live range.
3412 result_pos = array;
3413 array = no_reg;
3414 3421
3422 // Check that all array elements are sequential ascii strings, and
Lasse Reichstein 2011/01/13 09:20:32 ascii -> ASCII.
William Hesse 2011/01/13 16:25:59 Both forms occur in our comments, about 1/3 lowerc
3423 // accumulate the sum of their lengths.
Lasse Reichstein 2011/01/13 09:20:32 Say that the sum is maintained as a Smi value.
William Hesse 2011/01/13 16:25:59 Done.
3424 __ Set(index, Immediate(0));
3425 __ Set(current_string_length, Immediate(0));
3426 // Loop condition: while (index < length).
3427 // Live loop registers: index, array_length, current_string,
3428 // scratch, current_string_length, elements.
3429 __ jmp(&loop_condition);
3430 __ bind(&loop);
3431 __ cmp(index, Operand(array_length));
3432 __ j(greater_equal, &done);
3415 3433
3416 // Check that the separator is a flat ascii string. 3434 __ mov(current_string, FieldOperand(elements, index,
3417 __ mov(current_string, separator); 3435 times_pointer_size,
3436 FixedArray::kHeaderSize));
3418 __ test(current_string, Immediate(kSmiTagMask)); 3437 __ test(current_string, Immediate(kSmiTagMask));
3419 __ j(zero, &bailout); 3438 __ j(zero, &bailout);
3420 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset)); 3439 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset));
3421 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3440 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
Lasse Reichstein 2011/01/13 09:20:32 Use movzx_b to avoid depending on the remaining bi
William Hesse 2011/01/13 16:25:59 done.
3422 __ and_(scratch, Immediate( 3441 __ and_(scratch, Immediate(
3423 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3442 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
3424 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); 3443 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag);
3425 __ j(not_equal, &bailout); 3444 __ j(not_equal, &bailout);
3426 // If the separator is the empty string, replace it with NULL. 3445 __ add(current_string_length,
3427 // The test for NULL is quicker than the empty string test, in a loop. 3446 FieldOperand(current_string, SeqAsciiString::kLengthOffset));
3428 __ cmp(FieldOperand(current_string, SeqAsciiString::kLengthOffset), 3447 __ j(overflow, &bailout);
3429 Immediate(0)); 3448 __ add(Operand(index), Immediate(1));
3430 Label separator_checked; 3449 __ bind(&loop_condition);
3431 __ j(not_zero, &separator_checked); 3450 __ cmp(index, Operand(array_length));
3432 __ mov(separator, Immediate(0)); 3451 __ j(less, &loop);
3433 __ bind(&separator_checked);
3434 3452
3435 // Check that elements[0] is a flat ascii string, and copy it in new space. 3453 // If array_length is 1, return elements[0], a string.
3436 __ mov(scratch, elements); 3454 __ cmp(array_length, 1);
3437 __ mov(current_string, FieldOperand(scratch, FixedArray::kHeaderSize)); 3455 __ j(not_equal, &not_size_one_array);
3456 __ mov(scratch, FieldOperand(elements, FixedArray::kHeaderSize));
3457 __ mov(result_operand, scratch);
3458 __ jmp(&done);
3459
3460 __ bind(&not_size_one_array);
3461 // End of elements live range
3462 result_pos = elements;
3463 elements = no_reg;
3464
3465 // End of array_length live range.
3466 pos = array_length;
3467 array_length = no_reg;
3468
3469 // Live register:
3470 // current_string_length: Sum of string lengths, as a smi.
3471
3472 // Check that the separator is a flat ascii string.
Lasse Reichstein 2011/01/13 09:20:32 ASCII.
William Hesse 2011/01/13 16:25:59 Done.
3473 __ mov(current_string, separator_operand);
3438 __ test(current_string, Immediate(kSmiTagMask)); 3474 __ test(current_string, Immediate(kSmiTagMask));
3439 __ j(zero, &bailout); 3475 __ j(zero, &bailout);
3440 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset)); 3476 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset));
3441 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3477 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
3442 __ and_(scratch, Immediate( 3478 __ and_(scratch, Immediate(
3443 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3479 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
3444 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); 3480 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag);
3445 __ j(not_equal, &bailout); 3481 __ j(not_equal, &bailout);
3446 3482
3447 // Allocate space to copy it. Round up the size to the alignment granularity. 3483 // Add (separator length times array_length) - separator length
3448 __ mov(current_string_length, 3484 // to current_string_length.
3449 FieldOperand(current_string, String::kLengthOffset)); 3485 __ mov(scratch, separator_operand);
3450 __ shr(current_string_length, 1); 3486 __ mov(scratch, FieldOperand(scratch, SeqAsciiString::kLengthOffset));
3451 3487 __ sub(current_string_length, Operand(scratch));
Lasse Reichstein 2011/01/13 09:20:32 Perhaps worth noting that this can (and may) give
William Hesse 2011/01/13 16:25:59 Done.
3488 __ imul(scratch, array_length_operand);
3489 __ j(overflow, &bailout);
3490 __ add(current_string_length, Operand(scratch));
3491 __ j(overflow, &bailout);
3492
3493 __ shr(current_string_length, 1);
3452 // Live registers and stack values: 3494 // Live registers and stack values:
3453 // current_string_length: length of elements[0]. 3495 // current_string_length: length of elements[0].
3454 3496
3455 // New string result in new space = elements[0] 3497 // New string result in new space = elements[0]
3456 __ AllocateAsciiString(result_pos, current_string_length, scratch_2, 3498 __ AllocateAsciiString(result_pos, current_string_length, pos,
3457 index, no_reg, &bailout); 3499 index, current_string, &bailout);
3458 __ mov(result, result_pos); 3500 __ mov(result_operand, result_pos);
3459 3501 __ lea(result_pos, FieldOperand(result_pos, SeqAsciiString::kHeaderSize));
3460 // Adjust current_string_length to include padding bytes at end of string. 3502
3461 // Keep track of the number of padding bytes. 3503
3462 __ mov(new_padding_chars, current_string_length); 3504 __ mov(current_string, separator_operand);
3463 __ add(Operand(current_string_length), Immediate(kObjectAlignmentMask)); 3505 __ cmp(FieldOperand(current_string, SeqAsciiString::kLengthOffset),
3464 __ and_(Operand(current_string_length), Immediate(~kObjectAlignmentMask)); 3506 Immediate(Smi::FromInt(1)));
3465 __ sub(new_padding_chars, Operand(current_string_length)); 3507 __ j(equal, &one_char_separator);
3466 __ neg(new_padding_chars); 3508 __ j(greater, &long_separator);
3467 __ mov(padding_chars, new_padding_chars); 3509
3468 3510
3469 Label copy_loop_1_done; 3511 // Empty separator case
3470 Label copy_loop_1; 3512 __ mov(index, Immediate(0));
3471 __ test(current_string_length, Operand(current_string_length)); 3513 __ jmp(&loop_1_condition);
3472 __ j(zero, &copy_loop_1_done);
3473 __ bind(&copy_loop_1);
3474 __ sub(Operand(current_string_length), Immediate(kPointerSize));
3475 __ mov(scratch, FieldOperand(current_string, current_string_length,
3476 times_1, SeqAsciiString::kHeaderSize));
3477 __ mov(FieldOperand(result_pos, current_string_length,
3478 times_1, SeqAsciiString::kHeaderSize),
3479 scratch);
3480 __ j(not_zero, &copy_loop_1);
3481 __ bind(&copy_loop_1_done);
3482
3483 __ mov(index, Immediate(1));
3484 // Loop condition: while (index < length). 3514 // Loop condition: while (index < length).
3485 Label loop; 3515 __ bind(&loop_1);
3486 __ bind(&loop); 3516 // Each iteration of the loop concatenates one string to the result.
3487 __ cmp(index, array_length); 3517 // Live values in registers:
3488 __ j(greater_equal, &done); 3518 // index: which element of the elements array we are adding to the result.
3489 3519 // result_pos: the position to which we are currently copying characters.
3490 // If the separator is the empty string, signalled by NULL, skip it. 3520
3491 Label separator_done;
3492 __ mov(current_string, separator);
3493 __ test(current_string, Operand(current_string));
3494 __ j(zero, &separator_done);
3495
3496 // Append separator to result. It is known to be a flat ascii string.
3497 __ AppendStringToTopOfNewSpace(current_string, current_string_length,
3498 result_pos, scratch, scratch_2, result,
3499 padding_chars, &bailout);
3500 __ bind(&separator_done);
3501
3502 // Add next element of array to the end of the result.
3503 // Get current_string = array[index]. 3521 // Get current_string = array[index].
3504 __ mov(scratch, elements); 3522 __ mov(scratch, elements_operand);
3505 __ mov(current_string, FieldOperand(scratch, index, 3523 __ mov(current_string, FieldOperand(scratch, index,
3506 times_pointer_size, 3524 times_pointer_size,
3507 FixedArray::kHeaderSize)); 3525 FixedArray::kHeaderSize));
3508 // If current != flat ascii string drop result, return undefined. 3526 __ mov(current_string_length,
3509 __ test(current_string, Immediate(kSmiTagMask)); 3527 FieldOperand(current_string, String::kLengthOffset));
3510 __ j(zero, &bailout); 3528 __ shr(current_string_length, 1);
3511 __ mov(scratch, FieldOperand(current_string, HeapObject::kMapOffset)); 3529 __ lea(current_string,
3512 __ mov_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3530 FieldOperand(current_string, SeqAsciiString::kHeaderSize));
3513 __ and_(scratch, Immediate( 3531 __ Set(pos, Immediate(0));
3514 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3532 __ jmp(&loop_1a_condition);
3515 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); 3533
3516 __ j(not_equal, &bailout); 3534 __ bind(&loop_1a);
3517 3535 // Live registers:
3518 // Append current to the result. 3536 // current_string: the start of the current string's data.
3519 __ AppendStringToTopOfNewSpace(current_string, current_string_length, 3537 // pos: the index into the currently copied character of current_string.
3520 result_pos, scratch, scratch_2, result, 3538 // current_string_length: the length of the current string.
3521 padding_chars, &bailout); 3539 // scratch: the byte being copied.
3540 // result_pos: the position to copy the current string to.
3541 // index: which element of the array is being copied (live across loop).
3542 __ mov_b(scratch, Operand(current_string, pos, times_1, 0));
3543 __ mov_b(Operand(result_pos, pos, times_1, 0), scratch);
3544 __ inc(pos);
3545 __ bind(&loop_1a_condition);
3546 __ cmp(pos, Operand(current_string_length));
3547 __ j(less, &loop_1a);
3548
3549 __ add(result_pos, Operand(current_string_length));
3522 __ add(Operand(index), Immediate(1)); 3550 __ add(Operand(index), Immediate(1));
3523 __ jmp(&loop); // End while (index < length). 3551 __ bind(&loop_1_condition);
3552 __ cmp(index, array_length_operand);
3553 __ j(less, &loop_1); // End while (index < length).
3554 __ jmp(&done);
3555
3556
3557
3558 // One-character separator case
3559 __ bind(&one_char_separator);
3560 // Replace separator with its ascii character value.
3561 __ mov_b(scratch, FieldOperand(current_string, SeqAsciiString::kHeaderSize));
3562 __ mov_b(separator_operand, scratch);
3563
3564 __ Set(index, Immediate(0));
3565 // Jump into the loop after the code that copies the separator, so the first
3566 // element is not preceded by a separator
3567 __ jmp(&loop_2_entry);
3568 // Loop condition: while (index < length).
3569 __ bind(&loop_2);
3570 // Each iteration of the loop concatenates one string to the result.
3571 // Live values in registers:
3572 // index: which element of the elements array we are adding to the result.
3573 // result_pos: the position to which we are currently copying characters.
3574
3575 // Copy the separator character to the result.
3576 __ mov_b(scratch, separator_operand);
3577 __ mov_b(Operand(result_pos, 0), scratch);
3578 __ inc(result_pos);
3579
3580 __ bind(&loop_2_entry);
3581 // Get current_string = array[index].
3582 __ mov(scratch, elements_operand);
3583 __ mov(current_string, FieldOperand(scratch, index,
3584 times_pointer_size,
3585 FixedArray::kHeaderSize));
3586 __ mov(current_string_length,
3587 FieldOperand(current_string, String::kLengthOffset));
3588 __ shr(current_string_length, 1);
3589 __ lea(current_string,
3590 FieldOperand(current_string, SeqAsciiString::kHeaderSize));
3591 __ Set(pos, Immediate(0));
3592 __ jmp(&loop_2a_condition);
3593
3594 __ bind(&loop_2a);
3595 // Live registers:
3596 // current_string: the start of the current string's data.
3597 // pos: the index into the currently copied character of current_string.
3598 // current_string_length: the length of the current string.
3599 // scratch: the byte being copied.
3600 // result_pos: the position to copy the current string to.
3601 // index: which element of the array is being copied (live across loop).
3602 __ mov_b(scratch, Operand(current_string, pos, times_1, 0));
3603 __ mov_b(Operand(result_pos, pos, times_1, 0), scratch);
3604 __ inc(pos);
3605 __ bind(&loop_2a_condition);
3606 __ cmp(pos, Operand(current_string_length));
3607 __ j(less, &loop_2a);
3608
3609 __ add(result_pos, Operand(current_string_length));
3610 __ add(Operand(index), Immediate(1));
3611
3612 __ cmp(index, array_length_operand);
3613 __ j(less, &loop_2); // End while (index < length).
3614 __ jmp(&done);
3615
3616
3617 // Long separator case (separator is more than one character).
3618 __ bind(&long_separator);
3619
3620 __ Set(index, Immediate(0));
3621 // Jump into the loop after the code that copies the separator, so the first
3622 // element is not preceded by a separator
3623 __ jmp(&loop_3_entry);
3624 // Loop condition: while (index < length).
3625 __ bind(&loop_3);
3626 // Each iteration of the loop concatenates one string to the result.
3627 // Live values in registers:
3628 // index: which element of the elements array we are adding to the result.
3629 // result_pos: the position to which we are currently copying characters.
3630
3631 // Copy the separator to the result.
3632 __ mov(current_string, separator_operand);
3633 __ mov(current_string_length,
3634 FieldOperand(current_string, String::kLengthOffset));
3635 __ shr(current_string_length, 1);
3636 __ lea(current_string,
3637 FieldOperand(current_string, SeqAsciiString::kHeaderSize));
3638 __ Set(pos, Immediate(0));
3639 __ jmp(&loop_3a_condition);
3640
3641 __ bind(&loop_3a);
3642 // Live registers:
3643 // current_string: the start of the separator's data.
3644 // pos: the index into the currently copied character of separator.
3645 // current_string_length: the length of the separator.
3646 // scratch: the byte being copied.
3647 // result_pos: the position to copy the separator to.
3648 // index: which element of the array is being copied (live across loop).
3649 __ mov_b(scratch, Operand(current_string, pos, times_1, 0));
3650 __ mov_b(Operand(result_pos, pos, times_1, 0), scratch);
3651 __ inc(pos);
3652 __ bind(&loop_3a_condition);
3653 __ cmp(pos, Operand(current_string_length));
3654 __ j(less, &loop_3a);
3655
3656 __ add(result_pos, Operand(current_string_length));
3657
3658 __ bind(&loop_3_entry);
3659 // Get current_string = array[index].
3660 __ mov(scratch, elements_operand);
3661 __ mov(current_string, FieldOperand(scratch, index,
3662 times_pointer_size,
3663 FixedArray::kHeaderSize));
3664 __ mov(current_string_length,
3665 FieldOperand(current_string, String::kLengthOffset));
3666 __ shr(current_string_length, 1);
3667 __ lea(current_string,
3668 FieldOperand(current_string, SeqAsciiString::kHeaderSize));
3669 __ Set(pos, Immediate(0));
3670 __ jmp(&loop_3b_condition);
3671
3672 __ bind(&loop_3b);
3673 // Live registers:
3674 // current_string: the start of the current string's data.
3675 // pos: the index into the currently copied character of current_string.
3676 // current_string_length: the length of the current string.
3677 // scratch: the byte being copied.
3678 // result_pos: the position to copy the current string to.
3679 // index: which element of the array is being copied (live across loop).
3680 __ mov_b(scratch, Operand(current_string, pos, times_1, 0));
3681 __ mov_b(Operand(result_pos, pos, times_1, 0), scratch);
3682 __ inc(pos);
3683 __ bind(&loop_3b_condition);
3684 __ cmp(pos, Operand(current_string_length));
3685 __ j(less, &loop_3b);
3686
3687 __ add(result_pos, Operand(current_string_length));
3688 __ add(Operand(index), Immediate(1));
3689
3690 __ cmp(index, array_length_operand);
3691 __ j(less, &loop_3); // End while (index < length).
3692 __ jmp(&done);
3693
3524 3694
3525 __ bind(&bailout); 3695 __ bind(&bailout);
3526 __ mov(result, Factory::undefined_value()); 3696 __ mov(result_operand, Factory::undefined_value());
3527 __ bind(&done); 3697 __ bind(&done);
3528 __ mov(eax, result); 3698 __ mov(eax, result_operand);
3529 // Drop temp values from the stack, and restore context register. 3699 // Drop temp values from the stack, and restore context register.
3530 __ add(Operand(esp), Immediate(5 * kPointerSize)); 3700 __ add(Operand(esp), Immediate(4 * kPointerSize));
3531 3701
3532 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3702 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3533 context()->Plug(eax); 3703 context()->Plug(eax);
3534 } 3704 }
3535 3705
3536 3706
3537 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 3707 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
3538 Handle<String> name = expr->name(); 3708 Handle<String> name = expr->name();
3539 if (name->length() > 0 && name->Get(0) == '_') { 3709 if (name->length() > 0 && name->Get(0) == '_') {
3540 Comment cmnt(masm_, "[ InlineRuntimeCall"); 3710 Comment cmnt(masm_, "[ InlineRuntimeCall");
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
4273 // And return. 4443 // And return.
4274 __ ret(0); 4444 __ ret(0);
4275 } 4445 }
4276 4446
4277 4447
4278 #undef __ 4448 #undef __
4279 4449
4280 } } // namespace v8::internal 4450 } } // namespace v8::internal
4281 4451
4282 #endif // V8_TARGET_ARCH_IA32 4452 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698