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

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

Issue 1706013: Changing string length field type from int to SMI. It will make it be a regu... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 10 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 | Annotate | Revision Log
« no previous file with comments | « include/v8.h ('k') | src/arm/macro-assembler-arm.h » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 8480 matching lines...) Expand 10 before | Expand all | Expand 10 after
8491 // Check that the second argument is a string. 8491 // Check that the second argument is a string.
8492 __ ldr(subject, MemOperand(sp, kSubjectOffset)); 8492 __ ldr(subject, MemOperand(sp, kSubjectOffset));
8493 __ tst(subject, Operand(kSmiTagMask)); 8493 __ tst(subject, Operand(kSmiTagMask));
8494 __ b(eq, &runtime); 8494 __ b(eq, &runtime);
8495 Condition is_string = masm->IsObjectStringType(subject, r0); 8495 Condition is_string = masm->IsObjectStringType(subject, r0);
8496 __ b(NegateCondition(is_string), &runtime); 8496 __ b(NegateCondition(is_string), &runtime);
8497 // Get the length of the string to r3. 8497 // Get the length of the string to r3.
8498 __ ldr(r3, FieldMemOperand(subject, String::kLengthOffset)); 8498 __ ldr(r3, FieldMemOperand(subject, String::kLengthOffset));
8499 8499
8500 // r2: Number of capture registers 8500 // r2: Number of capture registers
8501 // r3: Length of subject string 8501 // r3: Length of subject string as a smi
8502 // subject: Subject string 8502 // subject: Subject string
8503 // regexp_data: RegExp data (FixedArray) 8503 // regexp_data: RegExp data (FixedArray)
8504 // Check that the third argument is a positive smi less than the subject 8504 // Check that the third argument is a positive smi less than the subject
8505 // string length. A negative value will be greater (unsigned comparison). 8505 // string length. A negative value will be greater (unsigned comparison).
8506 __ ldr(r0, MemOperand(sp, kPreviousIndexOffset)); 8506 __ ldr(r0, MemOperand(sp, kPreviousIndexOffset));
8507 __ cmp(r3, Operand(r0, ASR, kSmiTagSize + kSmiShiftSize)); 8507 __ tst(r0, Operand(kSmiTagMask));
8508 __ b(ls, &runtime); 8508 __ b(eq, &runtime);
8509 __ cmp(r3, Operand(r0));
8510 __ b(le, &runtime);
8509 8511
8510 // r2: Number of capture registers 8512 // r2: Number of capture registers
8511 // subject: Subject string 8513 // subject: Subject string
8512 // regexp_data: RegExp data (FixedArray) 8514 // regexp_data: RegExp data (FixedArray)
8513 // Check that the fourth object is a JSArray object. 8515 // Check that the fourth object is a JSArray object.
8514 __ ldr(r0, MemOperand(sp, kLastMatchInfoOffset)); 8516 __ ldr(r0, MemOperand(sp, kLastMatchInfoOffset));
8515 __ tst(r0, Operand(kSmiTagMask)); 8517 __ tst(r0, Operand(kSmiTagMask));
8516 __ b(eq, &runtime); 8518 __ b(eq, &runtime);
8517 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); 8519 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
8518 __ b(ne, &runtime); 8520 __ b(ne, &runtime);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
8624 __ add(r0, r0, Operand(r2)); 8626 __ add(r0, r0, Operand(r2));
8625 __ str(r0, MemOperand(sp, 1 * kPointerSize)); 8627 __ str(r0, MemOperand(sp, 1 * kPointerSize));
8626 8628
8627 // Argument 5 (sp[0]): static offsets vector buffer. 8629 // Argument 5 (sp[0]): static offsets vector buffer.
8628 __ mov(r0, Operand(ExternalReference::address_of_static_offsets_vector())); 8630 __ mov(r0, Operand(ExternalReference::address_of_static_offsets_vector()));
8629 __ str(r0, MemOperand(sp, 0 * kPointerSize)); 8631 __ str(r0, MemOperand(sp, 0 * kPointerSize));
8630 8632
8631 // For arguments 4 and 3 get string length, calculate start of string data and 8633 // For arguments 4 and 3 get string length, calculate start of string data and
8632 // calculate the shift of the index (0 for ASCII and 1 for two byte). 8634 // calculate the shift of the index (0 for ASCII and 1 for two byte).
8633 __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset)); 8635 __ ldr(r0, FieldMemOperand(subject, String::kLengthOffset));
8636 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
8634 ASSERT_EQ(SeqAsciiString::kHeaderSize, SeqTwoByteString::kHeaderSize); 8637 ASSERT_EQ(SeqAsciiString::kHeaderSize, SeqTwoByteString::kHeaderSize);
8635 __ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 8638 __ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
8636 __ eor(r3, r3, Operand(1)); 8639 __ eor(r3, r3, Operand(1));
8637 // Argument 4 (r3): End of string data 8640 // Argument 4 (r3): End of string data
8638 // Argument 3 (r2): Start of string data 8641 // Argument 3 (r2): Start of string data
8639 __ add(r2, r9, Operand(r1, LSL, r3)); 8642 __ add(r2, r9, Operand(r1, LSL, r3));
8640 __ add(r3, r9, Operand(r0, LSL, r3)); 8643 __ add(r3, r9, Operand(r0, LSL, r3));
8641 8644
8642 // Argument 2 (r1): Previous index. 8645 // Argument 2 (r1): Previous index.
8643 // Already there 8646 // Already there
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
8883 // If the receiver is not a string trigger the non-string case. 8886 // If the receiver is not a string trigger the non-string case.
8884 __ tst(result, Operand(kIsNotStringMask)); 8887 __ tst(result, Operand(kIsNotStringMask));
8885 __ b(ne, receiver_not_string); 8888 __ b(ne, receiver_not_string);
8886 8889
8887 // If the index is non-smi trigger the non-smi case. 8890 // If the index is non-smi trigger the non-smi case.
8888 __ BranchOnNotSmi(index, index_not_smi); 8891 __ BranchOnNotSmi(index, index_not_smi);
8889 8892
8890 // Check for index out of range. 8893 // Check for index out of range.
8891 __ ldr(scratch, FieldMemOperand(object, String::kLengthOffset)); 8894 __ ldr(scratch, FieldMemOperand(object, String::kLengthOffset));
8892 // Now scratch has the length of the string. Compare with the index. 8895 // Now scratch has the length of the string. Compare with the index.
8893 __ cmp(scratch, Operand(index, LSR, kSmiTagSize)); 8896 __ cmp(scratch, Operand(index));
8894 __ b(ls, index_out_of_range); 8897 __ b(ls, index_out_of_range);
8895 8898
8896 __ bind(&try_again_with_new_string); 8899 __ bind(&try_again_with_new_string);
8897 // ----------- S t a t e ------------- 8900 // ----------- S t a t e -------------
8898 // -- object : string to access 8901 // -- object : string to access
8899 // -- result : instance type of the string 8902 // -- result : instance type of the string
8900 // -- scratch : non-negative index < length 8903 // -- scratch : non-negative index < length
8901 // ----------------------------------- 8904 // -----------------------------------
8902 8905
8903 // We need special handling for non-flat strings. 8906 // We need special handling for non-flat strings.
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
9270 candidate, 9273 candidate,
9271 LSL, 9274 LSL,
9272 kPointerSizeLog2)); 9275 kPointerSizeLog2));
9273 9276
9274 // If entry is undefined no string with this hash can be found. 9277 // If entry is undefined no string with this hash can be found.
9275 __ cmp(candidate, undefined); 9278 __ cmp(candidate, undefined);
9276 __ b(eq, not_found); 9279 __ b(eq, not_found);
9277 9280
9278 // If length is not 2 the string is not a candidate. 9281 // If length is not 2 the string is not a candidate.
9279 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset)); 9282 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset));
9280 __ cmp(scratch, Operand(2)); 9283 __ cmp(scratch, Operand(Smi::FromInt(2)));
9281 __ b(ne, &next_probe[i]); 9284 __ b(ne, &next_probe[i]);
9282 9285
9283 // Check that the candidate is a non-external ascii string. 9286 // Check that the candidate is a non-external ascii string.
9284 __ ldr(scratch, FieldMemOperand(candidate, HeapObject::kMapOffset)); 9287 __ ldr(scratch, FieldMemOperand(candidate, HeapObject::kMapOffset));
9285 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); 9288 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
9286 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, 9289 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch,
9287 &next_probe[i]); 9290 &next_probe[i]);
9288 9291
9289 // Check if the two characters match. 9292 // Check if the two characters match.
9290 // Assumes that word load is little endian. 9293 // Assumes that word load is little endian.
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
9421 // Definitly a sequential string. 9424 // Definitly a sequential string.
9422 __ bind(&seq_string); 9425 __ bind(&seq_string);
9423 9426
9424 // r1: instance type. 9427 // r1: instance type.
9425 // r2: length 9428 // r2: length
9426 // r3: from index (untaged smi) 9429 // r3: from index (untaged smi)
9427 // r5: string 9430 // r5: string
9428 // r6: from (smi) 9431 // r6: from (smi)
9429 // r7: to (smi) 9432 // r7: to (smi)
9430 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset)); 9433 __ ldr(r4, FieldMemOperand(r5, String::kLengthOffset));
9431 __ cmp(r4, Operand(r7, ASR, 1)); 9434 __ cmp(r4, Operand(r7));
9432 __ b(lt, &runtime); // Fail if to > length. 9435 __ b(lt, &runtime); // Fail if to > length.
9433 9436
9434 // r1: instance type. 9437 // r1: instance type.
9435 // r2: result string length. 9438 // r2: result string length.
9436 // r3: from index (untaged smi) 9439 // r3: from index (untaged smi)
9437 // r5: string. 9440 // r5: string.
9438 // r6: from offset (smi) 9441 // r6: from offset (smi)
9439 // Check for flat ascii string. 9442 // Check for flat ascii string.
9440 Label non_ascii_flat; 9443 Label non_ascii_flat;
9441 __ tst(r1, Operand(kStringEncodingMask)); 9444 __ tst(r1, Operand(kStringEncodingMask));
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
9540 Register scratch3, 9543 Register scratch3,
9541 Register scratch4) { 9544 Register scratch4) {
9542 Label compare_lengths; 9545 Label compare_lengths;
9543 // Find minimum length and length difference. 9546 // Find minimum length and length difference.
9544 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); 9547 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
9545 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset)); 9548 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
9546 __ sub(scratch3, scratch1, Operand(scratch2), SetCC); 9549 __ sub(scratch3, scratch1, Operand(scratch2), SetCC);
9547 Register length_delta = scratch3; 9550 Register length_delta = scratch3;
9548 __ mov(scratch1, scratch2, LeaveCC, gt); 9551 __ mov(scratch1, scratch2, LeaveCC, gt);
9549 Register min_length = scratch1; 9552 Register min_length = scratch1;
9553 ASSERT(kSmiTag == 0);
9550 __ tst(min_length, Operand(min_length)); 9554 __ tst(min_length, Operand(min_length));
9551 __ b(eq, &compare_lengths); 9555 __ b(eq, &compare_lengths);
9552 9556
9557 // Untag smi.
9558 __ mov(min_length, Operand(min_length, ASR, kSmiTagSize));
9559
9553 // Setup registers so that we only need to increment one register 9560 // Setup registers so that we only need to increment one register
9554 // in the loop. 9561 // in the loop.
9555 __ add(scratch2, min_length, 9562 __ add(scratch2, min_length,
9556 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 9563 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
9557 __ add(left, left, Operand(scratch2)); 9564 __ add(left, left, Operand(scratch2));
9558 __ add(right, right, Operand(scratch2)); 9565 __ add(right, right, Operand(scratch2));
9559 // Registers left and right points to the min_length character of strings. 9566 // Registers left and right points to the min_length character of strings.
9560 __ rsb(min_length, min_length, Operand(-1)); 9567 __ rsb(min_length, min_length, Operand(-1));
9561 Register index = min_length; 9568 Register index = min_length;
9562 // Index starts at -min_length. 9569 // Index starts at -min_length.
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
9652 // Both arguments are strings. 9659 // Both arguments are strings.
9653 // r0: first string 9660 // r0: first string
9654 // r1: second string 9661 // r1: second string
9655 // r4: first string instance type (if string_check_) 9662 // r4: first string instance type (if string_check_)
9656 // r5: second string instance type (if string_check_) 9663 // r5: second string instance type (if string_check_)
9657 { 9664 {
9658 Label strings_not_empty; 9665 Label strings_not_empty;
9659 // Check if either of the strings are empty. In that case return the other. 9666 // Check if either of the strings are empty. In that case return the other.
9660 __ ldr(r2, FieldMemOperand(r0, String::kLengthOffset)); 9667 __ ldr(r2, FieldMemOperand(r0, String::kLengthOffset));
9661 __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset)); 9668 __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset));
9662 __ cmp(r2, Operand(0)); // Test if first string is empty. 9669 ASSERT(kSmiTag == 0);
9670 __ cmp(r2, Operand(Smi::FromInt(0))); // Test if first string is empty.
9663 __ mov(r0, Operand(r1), LeaveCC, eq); // If first is empty, return second. 9671 __ mov(r0, Operand(r1), LeaveCC, eq); // If first is empty, return second.
9664 __ cmp(r3, Operand(0), ne); // Else test if second string is empty. 9672 ASSERT(kSmiTag == 0);
9673 // Else test if second string is empty.
9674 __ cmp(r3, Operand(Smi::FromInt(0)), ne);
9665 __ b(ne, &strings_not_empty); // If either string was empty, return r0. 9675 __ b(ne, &strings_not_empty); // If either string was empty, return r0.
9666 9676
9667 __ IncrementCounter(&Counters::string_add_native, 1, r2, r3); 9677 __ IncrementCounter(&Counters::string_add_native, 1, r2, r3);
9668 __ add(sp, sp, Operand(2 * kPointerSize)); 9678 __ add(sp, sp, Operand(2 * kPointerSize));
9669 __ Ret(); 9679 __ Ret();
9670 9680
9671 __ bind(&strings_not_empty); 9681 __ bind(&strings_not_empty);
9672 } 9682 }
9673 9683
9684 __ mov(r2, Operand(r2, ASR, kSmiTagSize));
9685 __ mov(r3, Operand(r3, ASR, kSmiTagSize));
9674 // Both strings are non-empty. 9686 // Both strings are non-empty.
9675 // r0: first string 9687 // r0: first string
9676 // r1: second string 9688 // r1: second string
9677 // r2: length of first string 9689 // r2: length of first string
9678 // r3: length of second string 9690 // r3: length of second string
9679 // r4: first string instance type (if string_check_) 9691 // r4: first string instance type (if string_check_)
9680 // r5: second string instance type (if string_check_) 9692 // r5: second string instance type (if string_check_)
9681 // Look at the length of the result of adding the two strings. 9693 // Look at the length of the result of adding the two strings.
9682 Label string_add_flat_result, longer_than_two; 9694 Label string_add_flat_result, longer_than_two;
9683 // Adding two lengths can't overflow. 9695 // Adding two lengths can't overflow.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
9872 9884
9873 // Just jump to runtime to add the two strings. 9885 // Just jump to runtime to add the two strings.
9874 __ bind(&string_add_runtime); 9886 __ bind(&string_add_runtime);
9875 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 9887 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
9876 } 9888 }
9877 9889
9878 9890
9879 #undef __ 9891 #undef __
9880 9892
9881 } } // namespace v8::internal 9893 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « include/v8.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698