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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 6928020: Faster string equals in generated code. (Closed)
Patch Set: Created 9 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
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 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 EmitCheckForSymbolsOrObjects(masm, lhs_, rhs_, &flat_string_check, &slow); 1561 EmitCheckForSymbolsOrObjects(masm, lhs_, rhs_, &flat_string_check, &slow);
1562 } 1562 }
1563 1563
1564 // Check for both being sequential ASCII strings, and inline if that is the 1564 // Check for both being sequential ASCII strings, and inline if that is the
1565 // case. 1565 // case.
1566 __ bind(&flat_string_check); 1566 __ bind(&flat_string_check);
1567 1567
1568 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow); 1568 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs_, rhs_, r2, r3, &slow);
1569 1569
1570 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3); 1570 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3);
1571 StringCompareStub::GenerateCompareFlatAsciiStrings(masm, 1571 if (cc_ == eq) {
1572 StringCompareStub::GenerateFlatAsciiStringEquals(masm,
1572 lhs_, 1573 lhs_,
1573 rhs_, 1574 rhs_,
1574 r2, 1575 r2,
1575 r3, 1576 r3,
1576 r4, 1577 r4);
1577 r5); 1578 } else {
1579 StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
1580 lhs_,
1581 rhs_,
1582 r2,
1583 r3,
1584 r4,
1585 r5);
1586 }
1578 // Never falls through to here. 1587 // Never falls through to here.
1579 1588
1580 __ bind(&slow); 1589 __ bind(&slow);
1581 1590
1582 __ Push(lhs_, rhs_); 1591 __ Push(lhs_, rhs_);
1583 // Figure out which native to call and setup the arguments. 1592 // Figure out which native to call and setup the arguments.
1584 Builtins::JavaScript native; 1593 Builtins::JavaScript native;
1585 if (cc_ == eq) { 1594 if (cc_ == eq) {
1586 native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS; 1595 native = strict_ ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
1587 } else { 1596 } else {
(...skipping 3797 matching lines...) Expand 10 before | Expand all | Expand 10 after
5385 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4); 5394 __ IncrementCounter(counters->sub_string_native(), 1, r3, r4);
5386 __ add(sp, sp, Operand(3 * kPointerSize)); 5395 __ add(sp, sp, Operand(3 * kPointerSize));
5387 __ Ret(); 5396 __ Ret();
5388 5397
5389 // Just jump to runtime to create the sub string. 5398 // Just jump to runtime to create the sub string.
5390 __ bind(&runtime); 5399 __ bind(&runtime);
5391 __ TailCallRuntime(Runtime::kSubString, 3, 1); 5400 __ TailCallRuntime(Runtime::kSubString, 3, 1);
5392 } 5401 }
5393 5402
5394 5403
5404 void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm,
5405 Register left,
5406 Register right,
5407 Register scratch1,
5408 Register scratch2,
5409 Register scratch3) {
5410 Register length = scratch1;
5411
5412 // Compare lengths.
5413 Label strings_not_equal, check_zero_length;
5414 __ ldr(length, FieldMemOperand(left, String::kLengthOffset));
5415 __ ldr(scratch2, FieldMemOperand(right, String::kLengthOffset));
5416 __ cmp(length, scratch2);
5417 __ b(eq, &check_zero_length);
5418 __ bind(&strings_not_equal);
5419 __ mov(r0, Operand(Smi::FromInt(NOT_EQUAL)));
5420 __ Ret();
5421
5422 // Check if the length is zero.
5423 Label compare_chars;
5424 __ bind(&check_zero_length);
5425 STATIC_ASSERT(kSmiTag == 0);
5426 __ tst(length, Operand(length));
5427 __ b(ne, &compare_chars);
5428 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
5429 __ Ret();
5430
5431 // Compare characters.
5432 __ bind(&compare_chars);
5433
5434 // Change index to run from -length to -1 by adding length to string
5435 // start. This means that loop ends when index reaches zero, which
5436 // doesn't need an additional compare.
5437 __ SmiUntag(length);
5438 __ add(scratch2, length,
5439 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
5440 __ add(left, left, Operand(scratch2));
5441 __ add(right, right, Operand(scratch2));
5442 __ rsb(length, length, Operand(0));
5443 Register index = length; // index = -length;
5444
5445 // Compare loop.
5446 Label loop;
5447 __ bind(&loop);
5448 __ ldrb(scratch2, MemOperand(left, index));
5449 __ ldrb(scratch3, MemOperand(right, index));
5450 __ cmp(scratch2, scratch3);
5451 __ b(ne, &strings_not_equal);
5452 __ add(index, index, Operand(1), SetCC);
5453 __ b(ne, &loop);
5454
5455 // Characters are equal.
5456 __ mov(r0, Operand(Smi::FromInt(EQUAL)));
5457 __ Ret();
5458 }
5459
5460
5395 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, 5461 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
5396 Register left, 5462 Register left,
5397 Register right, 5463 Register right,
5398 Register scratch1, 5464 Register scratch1,
5399 Register scratch2, 5465 Register scratch2,
5400 Register scratch3, 5466 Register scratch3,
5401 Register scratch4) { 5467 Register scratch4) {
5402 Label compare_lengths; 5468 Label compare_lengths;
5403 // Find minimum length and length difference. 5469 // Find minimum length and length difference.
5404 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset)); 5470 __ ldr(scratch1, FieldMemOperand(left, String::kLengthOffset));
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
5948 // guaranteed to be non-zero. 6014 // guaranteed to be non-zero.
5949 ASSERT(right.is(r0)); 6015 ASSERT(right.is(r0));
5950 __ Ret(ne); 6016 __ Ret(ne);
5951 6017
5952 // Check that both strings are sequential ASCII. 6018 // Check that both strings are sequential ASCII.
5953 Label runtime; 6019 Label runtime;
5954 __ JumpIfBothInstanceTypesAreNotSequentialAscii(tmp1, tmp2, tmp3, tmp4, 6020 __ JumpIfBothInstanceTypesAreNotSequentialAscii(tmp1, tmp2, tmp3, tmp4,
5955 &runtime); 6021 &runtime);
5956 6022
5957 // Compare flat ASCII strings. Returns when done. 6023 // Compare flat ASCII strings. Returns when done.
5958 StringCompareStub::GenerateCompareFlatAsciiStrings( 6024 StringCompareStub::GenerateFlatAsciiStringEquals(
5959 masm, left, right, tmp1, tmp2, tmp3, tmp4); 6025 masm, left, right, tmp1, tmp2, tmp3);
5960 6026
5961 // Handle more complex cases in runtime. 6027 // Handle more complex cases in runtime.
5962 __ bind(&runtime); 6028 __ bind(&runtime);
5963 __ Push(left, right); 6029 __ Push(left, right);
5964 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 6030 __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
5965 6031
5966 __ bind(&miss); 6032 __ bind(&miss);
5967 GenerateMiss(masm); 6033 GenerateMiss(masm);
5968 } 6034 }
5969 6035
5970 6036
5971 void ICCompareStub::GenerateObjects(MacroAssembler* masm) { 6037 void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
5972 ASSERT(state_ == CompareIC::OBJECTS); 6038 ASSERT(state_ == CompareIC::OBJECTS);
5973 Label miss; 6039 Label miss;
5974 __ and_(r2, r1, Operand(r0)); 6040 __ and_(r2, r1, Operand(r0));
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
6036 __ str(pc, MemOperand(sp, 0)); 6102 __ str(pc, MemOperand(sp, 0));
6037 __ Jump(target); // Call the C++ function. 6103 __ Jump(target); // Call the C++ function.
6038 } 6104 }
6039 6105
6040 6106
6041 #undef __ 6107 #undef __
6042 6108
6043 } } // namespace v8::internal 6109 } } // namespace v8::internal
6044 6110
6045 #endif // V8_TARGET_ARCH_ARM 6111 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698