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

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

Issue 12210083: Renamed "symbols" to "internalized strings" throughout the code base, (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Yang's comments Created 7 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/codegen-arm.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 // 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 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 __ cmp(r2, Operand(ODDBALL_TYPE)); 1528 __ cmp(r2, Operand(ODDBALL_TYPE));
1529 __ b(eq, &return_not_equal); 1529 __ b(eq, &return_not_equal);
1530 1530
1531 __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE); 1531 __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE);
1532 __ b(ge, &return_not_equal); 1532 __ b(ge, &return_not_equal);
1533 1533
1534 // Check for oddballs: true, false, null, undefined. 1534 // Check for oddballs: true, false, null, undefined.
1535 __ cmp(r3, Operand(ODDBALL_TYPE)); 1535 __ cmp(r3, Operand(ODDBALL_TYPE));
1536 __ b(eq, &return_not_equal); 1536 __ b(eq, &return_not_equal);
1537 1537
1538 // Now that we have the types we might as well check for symbol-symbol. 1538 // Now that we have the types we might as well check for
1539 // Ensure that no non-strings have the symbol bit set. 1539 // internalized-internalized.
1540 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsSymbolMask); 1540 // Ensure that no non-strings have the internalized bit set.
1541 STATIC_ASSERT(kSymbolTag != 0); 1541 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsInternalizedMask);
1542 STATIC_ASSERT(kInternalizedTag != 0);
1542 __ and_(r2, r2, Operand(r3)); 1543 __ and_(r2, r2, Operand(r3));
1543 __ tst(r2, Operand(kIsSymbolMask)); 1544 __ tst(r2, Operand(kIsInternalizedMask));
1544 __ b(ne, &return_not_equal); 1545 __ b(ne, &return_not_equal);
1545 } 1546 }
1546 1547
1547 1548
1548 // See comment at call site. 1549 // See comment at call site.
1549 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, 1550 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm,
1550 Register lhs, 1551 Register lhs,
1551 Register rhs, 1552 Register rhs,
1552 Label* both_loaded_as_doubles, 1553 Label* both_loaded_as_doubles,
1553 Label* not_heap_numbers, 1554 Label* not_heap_numbers,
(...skipping 16 matching lines...) Expand all
1570 __ sub(r7, lhs, Operand(kHeapObjectTag)); 1571 __ sub(r7, lhs, Operand(kHeapObjectTag));
1571 __ vldr(d7, r7, HeapNumber::kValueOffset); 1572 __ vldr(d7, r7, HeapNumber::kValueOffset);
1572 } else { 1573 } else {
1573 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset)); 1574 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset));
1574 __ Ldrd(r0, r1, FieldMemOperand(rhs, HeapNumber::kValueOffset)); 1575 __ Ldrd(r0, r1, FieldMemOperand(rhs, HeapNumber::kValueOffset));
1575 } 1576 }
1576 __ jmp(both_loaded_as_doubles); 1577 __ jmp(both_loaded_as_doubles);
1577 } 1578 }
1578 1579
1579 1580
1580 // Fast negative check for symbol-to-symbol equality. 1581 // Fast negative check for internalized-to-internalized equality.
1581 static void EmitCheckForSymbolsOrObjects(MacroAssembler* masm, 1582 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
1582 Register lhs, 1583 Register lhs,
1583 Register rhs, 1584 Register rhs,
1584 Label* possible_strings, 1585 Label* possible_strings,
1585 Label* not_both_strings) { 1586 Label* not_both_strings) {
1586 ASSERT((lhs.is(r0) && rhs.is(r1)) || 1587 ASSERT((lhs.is(r0) && rhs.is(r1)) ||
1587 (lhs.is(r1) && rhs.is(r0))); 1588 (lhs.is(r1) && rhs.is(r0)));
1588 1589
1589 // r2 is object type of rhs. 1590 // r2 is object type of rhs.
1590 // Ensure that no non-strings have the symbol bit set. 1591 // Ensure that no non-strings have the internalized bit set.
1591 Label object_test; 1592 Label object_test;
1592 STATIC_ASSERT(kSymbolTag != 0); 1593 STATIC_ASSERT(kInternalizedTag != 0);
1593 __ tst(r2, Operand(kIsNotStringMask)); 1594 __ tst(r2, Operand(kIsNotStringMask));
1594 __ b(ne, &object_test); 1595 __ b(ne, &object_test);
1595 __ tst(r2, Operand(kIsSymbolMask)); 1596 __ tst(r2, Operand(kIsInternalizedMask));
1596 __ b(eq, possible_strings); 1597 __ b(eq, possible_strings);
1597 __ CompareObjectType(lhs, r3, r3, FIRST_NONSTRING_TYPE); 1598 __ CompareObjectType(lhs, r3, r3, FIRST_NONSTRING_TYPE);
1598 __ b(ge, not_both_strings); 1599 __ b(ge, not_both_strings);
1599 __ tst(r3, Operand(kIsSymbolMask)); 1600 __ tst(r3, Operand(kIsInternalizedMask));
1600 __ b(eq, possible_strings); 1601 __ b(eq, possible_strings);
1601 1602
1602 // Both are symbols. We already checked they weren't the same pointer 1603 // Both are internalized. We already checked they weren't the same pointer
1603 // so they are not equal. 1604 // so they are not equal.
1604 __ mov(r0, Operand(NOT_EQUAL)); 1605 __ mov(r0, Operand(NOT_EQUAL));
1605 __ Ret(); 1606 __ Ret();
1606 1607
1607 __ bind(&object_test); 1608 __ bind(&object_test);
1608 __ cmp(r2, Operand(FIRST_SPEC_OBJECT_TYPE)); 1609 __ cmp(r2, Operand(FIRST_SPEC_OBJECT_TYPE));
1609 __ b(lt, not_both_strings); 1610 __ b(lt, not_both_strings);
1610 __ CompareObjectType(lhs, r2, r3, FIRST_SPEC_OBJECT_TYPE); 1611 __ CompareObjectType(lhs, r2, r3, FIRST_SPEC_OBJECT_TYPE);
1611 __ b(lt, not_both_strings); 1612 __ b(lt, not_both_strings);
1612 // If both objects are undetectable, they are equal. Otherwise, they 1613 // If both objects are undetectable, they are equal. Otherwise, they
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 CompareIC::State expected, 1740 CompareIC::State expected,
1740 Label* fail) { 1741 Label* fail) {
1741 Label ok; 1742 Label ok;
1742 if (expected == CompareIC::SMI) { 1743 if (expected == CompareIC::SMI) {
1743 __ JumpIfNotSmi(input, fail); 1744 __ JumpIfNotSmi(input, fail);
1744 } else if (expected == CompareIC::HEAP_NUMBER) { 1745 } else if (expected == CompareIC::HEAP_NUMBER) {
1745 __ JumpIfSmi(input, &ok); 1746 __ JumpIfSmi(input, &ok);
1746 __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail, 1747 __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail,
1747 DONT_DO_SMI_CHECK); 1748 DONT_DO_SMI_CHECK);
1748 } 1749 }
1749 // We could be strict about symbol/string here, but as long as 1750 // We could be strict about internalized/non-internalized here, but as long as
1750 // hydrogen doesn't care, the stub doesn't have to care either. 1751 // hydrogen doesn't care, the stub doesn't have to care either.
1751 __ bind(&ok); 1752 __ bind(&ok);
1752 } 1753 }
1753 1754
1754 1755
1755 // On entry r1 and r2 are the values to be compared. 1756 // On entry r1 and r2 are the values to be compared.
1756 // On exit r0 is 0, positive or negative to indicate the result of 1757 // On exit r0 is 0, positive or negative to indicate the result of
1757 // the comparison. 1758 // the comparison.
1758 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { 1759 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
1759 Register lhs = r1; 1760 Register lhs = r1;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 1838
1838 __ bind(&not_smis); 1839 __ bind(&not_smis);
1839 // At this point we know we are dealing with two different objects, 1840 // At this point we know we are dealing with two different objects,
1840 // and neither of them is a Smi. The objects are in rhs_ and lhs_. 1841 // and neither of them is a Smi. The objects are in rhs_ and lhs_.
1841 if (strict()) { 1842 if (strict()) {
1842 // This returns non-equal for some object types, or falls through if it 1843 // This returns non-equal for some object types, or falls through if it
1843 // was not lucky. 1844 // was not lucky.
1844 EmitStrictTwoHeapObjectCompare(masm, lhs, rhs); 1845 EmitStrictTwoHeapObjectCompare(masm, lhs, rhs);
1845 } 1846 }
1846 1847
1847 Label check_for_symbols; 1848 Label check_for_internalized_strings;
1848 Label flat_string_check; 1849 Label flat_string_check;
1849 // Check for heap-number-heap-number comparison. Can jump to slow case, 1850 // Check for heap-number-heap-number comparison. Can jump to slow case,
1850 // or load both doubles into r0, r1, r2, r3 and jump to the code that handles 1851 // or load both doubles into r0, r1, r2, r3 and jump to the code that handles
1851 // that case. If the inputs are not doubles then jumps to check_for_symbols. 1852 // that case. If the inputs are not doubles then jumps to
1853 // check_for_internalized_strings.
1852 // In this case r2 will contain the type of rhs_. Never falls through. 1854 // In this case r2 will contain the type of rhs_. Never falls through.
1853 EmitCheckForTwoHeapNumbers(masm, 1855 EmitCheckForTwoHeapNumbers(masm,
1854 lhs, 1856 lhs,
1855 rhs, 1857 rhs,
1856 &both_loaded_as_doubles, 1858 &both_loaded_as_doubles,
1857 &check_for_symbols, 1859 &check_for_internalized_strings,
1858 &flat_string_check); 1860 &flat_string_check);
1859 1861
1860 __ bind(&check_for_symbols); 1862 __ bind(&check_for_internalized_strings);
1861 // In the strict case the EmitStrictTwoHeapObjectCompare already took care of 1863 // In the strict case the EmitStrictTwoHeapObjectCompare already took care of
1862 // symbols. 1864 // internalized strings.
1863 if (cc == eq && !strict()) { 1865 if (cc == eq && !strict()) {
1864 // Returns an answer for two symbols or two detectable objects. 1866 // Returns an answer for two internalized strings or two detectable objects.
1865 // Otherwise jumps to string case or not both strings case. 1867 // Otherwise jumps to string case or not both strings case.
1866 // Assumes that r2 is the type of rhs_ on entry. 1868 // Assumes that r2 is the type of rhs_ on entry.
1867 EmitCheckForSymbolsOrObjects(masm, lhs, rhs, &flat_string_check, &slow); 1869 EmitCheckForInternalizedStringsOrObjects(
1870 masm, lhs, rhs, &flat_string_check, &slow);
1868 } 1871 }
1869 1872
1870 // Check for both being sequential ASCII strings, and inline if that is the 1873 // Check for both being sequential ASCII strings, and inline if that is the
1871 // case. 1874 // case.
1872 __ bind(&flat_string_check); 1875 __ bind(&flat_string_check);
1873 1876
1874 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow); 1877 __ JumpIfNonSmisNotBothSequentialAsciiStrings(lhs, rhs, r2, r3, &slow);
1875 1878
1876 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3); 1879 __ IncrementCounter(isolate->counters()->string_compare_native(), 1, r2, r3);
1877 if (cc == eq) { 1880 if (cc == eq) {
(...skipping 2648 matching lines...) Expand 10 before | Expand all | Expand 10 after
4526 4529
4527 void ArrayLengthStub::Generate(MacroAssembler* masm) { 4530 void ArrayLengthStub::Generate(MacroAssembler* masm) {
4528 Label miss; 4531 Label miss;
4529 Register receiver; 4532 Register receiver;
4530 if (kind() == Code::KEYED_LOAD_IC) { 4533 if (kind() == Code::KEYED_LOAD_IC) {
4531 // ----------- S t a t e ------------- 4534 // ----------- S t a t e -------------
4532 // -- lr : return address 4535 // -- lr : return address
4533 // -- r0 : key 4536 // -- r0 : key
4534 // -- r1 : receiver 4537 // -- r1 : receiver
4535 // ----------------------------------- 4538 // -----------------------------------
4536 __ cmp(r0, Operand(masm->isolate()->factory()->length_symbol())); 4539 __ cmp(r0, Operand(masm->isolate()->factory()->length_string()));
4537 __ b(ne, &miss); 4540 __ b(ne, &miss);
4538 receiver = r1; 4541 receiver = r1;
4539 } else { 4542 } else {
4540 ASSERT(kind() == Code::LOAD_IC); 4543 ASSERT(kind() == Code::LOAD_IC);
4541 // ----------- S t a t e ------------- 4544 // ----------- S t a t e -------------
4542 // -- r2 : name 4545 // -- r2 : name
4543 // -- lr : return address 4546 // -- lr : return address
4544 // -- r0 : receiver 4547 // -- r0 : receiver
4545 // -- sp[0] : receiver 4548 // -- sp[0] : receiver
4546 // ----------------------------------- 4549 // -----------------------------------
4547 receiver = r0; 4550 receiver = r0;
4548 } 4551 }
4549 4552
4550 StubCompiler::GenerateLoadArrayLength(masm, receiver, r3, &miss); 4553 StubCompiler::GenerateLoadArrayLength(masm, receiver, r3, &miss);
4551 __ bind(&miss); 4554 __ bind(&miss);
4552 StubCompiler::GenerateLoadMiss(masm, kind()); 4555 StubCompiler::GenerateLoadMiss(masm, kind());
4553 } 4556 }
4554 4557
4555 4558
4556 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 4559 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
4557 Label miss; 4560 Label miss;
4558 Register receiver; 4561 Register receiver;
4559 if (kind() == Code::KEYED_LOAD_IC) { 4562 if (kind() == Code::KEYED_LOAD_IC) {
4560 // ----------- S t a t e ------------- 4563 // ----------- S t a t e -------------
4561 // -- lr : return address 4564 // -- lr : return address
4562 // -- r0 : key 4565 // -- r0 : key
4563 // -- r1 : receiver 4566 // -- r1 : receiver
4564 // ----------------------------------- 4567 // -----------------------------------
4565 __ cmp(r0, Operand(masm->isolate()->factory()->prototype_symbol())); 4568 __ cmp(r0, Operand(masm->isolate()->factory()->prototype_string()));
4566 __ b(ne, &miss); 4569 __ b(ne, &miss);
4567 receiver = r1; 4570 receiver = r1;
4568 } else { 4571 } else {
4569 ASSERT(kind() == Code::LOAD_IC); 4572 ASSERT(kind() == Code::LOAD_IC);
4570 // ----------- S t a t e ------------- 4573 // ----------- S t a t e -------------
4571 // -- r2 : name 4574 // -- r2 : name
4572 // -- lr : return address 4575 // -- lr : return address
4573 // -- r0 : receiver 4576 // -- r0 : receiver
4574 // -- sp[0] : receiver 4577 // -- sp[0] : receiver
4575 // ----------------------------------- 4578 // -----------------------------------
4576 receiver = r0; 4579 receiver = r0;
4577 } 4580 }
4578 4581
4579 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r3, r4, &miss); 4582 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r3, r4, &miss);
4580 __ bind(&miss); 4583 __ bind(&miss);
4581 StubCompiler::GenerateLoadMiss(masm, kind()); 4584 StubCompiler::GenerateLoadMiss(masm, kind());
4582 } 4585 }
4583 4586
4584 4587
4585 void StringLengthStub::Generate(MacroAssembler* masm) { 4588 void StringLengthStub::Generate(MacroAssembler* masm) {
4586 Label miss; 4589 Label miss;
4587 Register receiver; 4590 Register receiver;
4588 if (kind() == Code::KEYED_LOAD_IC) { 4591 if (kind() == Code::KEYED_LOAD_IC) {
4589 // ----------- S t a t e ------------- 4592 // ----------- S t a t e -------------
4590 // -- lr : return address 4593 // -- lr : return address
4591 // -- r0 : key 4594 // -- r0 : key
4592 // -- r1 : receiver 4595 // -- r1 : receiver
4593 // ----------------------------------- 4596 // -----------------------------------
4594 __ cmp(r0, Operand(masm->isolate()->factory()->length_symbol())); 4597 __ cmp(r0, Operand(masm->isolate()->factory()->length_string()));
4595 __ b(ne, &miss); 4598 __ b(ne, &miss);
4596 receiver = r1; 4599 receiver = r1;
4597 } else { 4600 } else {
4598 ASSERT(kind() == Code::LOAD_IC); 4601 ASSERT(kind() == Code::LOAD_IC);
4599 // ----------- S t a t e ------------- 4602 // ----------- S t a t e -------------
4600 // -- r2 : name 4603 // -- r2 : name
4601 // -- lr : return address 4604 // -- lr : return address
4602 // -- r0 : receiver 4605 // -- r0 : receiver
4603 // -- sp[0] : receiver 4606 // -- sp[0] : receiver
4604 // ----------------------------------- 4607 // -----------------------------------
(...skipping 17 matching lines...) Expand all
4622 4625
4623 Register receiver; 4626 Register receiver;
4624 Register value; 4627 Register value;
4625 if (kind() == Code::KEYED_STORE_IC) { 4628 if (kind() == Code::KEYED_STORE_IC) {
4626 // ----------- S t a t e ------------- 4629 // ----------- S t a t e -------------
4627 // -- lr : return address 4630 // -- lr : return address
4628 // -- r0 : value 4631 // -- r0 : value
4629 // -- r1 : key 4632 // -- r1 : key
4630 // -- r2 : receiver 4633 // -- r2 : receiver
4631 // ----------------------------------- 4634 // -----------------------------------
4632 __ cmp(r1, Operand(masm->isolate()->factory()->length_symbol())); 4635 __ cmp(r1, Operand(masm->isolate()->factory()->length_string()));
4633 __ b(ne, &miss); 4636 __ b(ne, &miss);
4634 receiver = r2; 4637 receiver = r2;
4635 value = r0; 4638 value = r0;
4636 } else { 4639 } else {
4637 ASSERT(kind() == Code::STORE_IC); 4640 ASSERT(kind() == Code::STORE_IC);
4638 // ----------- S t a t e ------------- 4641 // ----------- S t a t e -------------
4639 // -- lr : return address 4642 // -- lr : return address
4640 // -- r0 : value 4643 // -- r0 : value
4641 // -- r1 : receiver 4644 // -- r1 : receiver
4642 // -- r2 : key 4645 // -- r2 : key
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
5226 5229
5227 // String is sliced. 5230 // String is sliced.
5228 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); 5231 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
5229 __ mov(r9, Operand(r9, ASR, kSmiTagSize)); 5232 __ mov(r9, Operand(r9, ASR, kSmiTagSize));
5230 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); 5233 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
5231 // r9: offset of sliced string, smi-tagged. 5234 // r9: offset of sliced string, smi-tagged.
5232 __ jmp(&check_encoding); 5235 __ jmp(&check_encoding);
5233 // String is a cons string, check whether it is flat. 5236 // String is a cons string, check whether it is flat.
5234 __ bind(&cons_string); 5237 __ bind(&cons_string);
5235 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset)); 5238 __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset));
5236 __ CompareRoot(r0, Heap::kEmptyStringRootIndex); 5239 __ CompareRoot(r0, Heap::kempty_stringRootIndex);
5237 __ b(ne, &runtime); 5240 __ b(ne, &runtime);
5238 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); 5241 __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
5239 // Is first part of cons or parent of slice a flat string? 5242 // Is first part of cons or parent of slice a flat string?
5240 __ bind(&check_encoding); 5243 __ bind(&check_encoding);
5241 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); 5244 __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
5242 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset)); 5245 __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
5243 STATIC_ASSERT(kSeqStringTag == 0); 5246 STATIC_ASSERT(kSeqStringTag == 0);
5244 __ tst(r0, Operand(kStringRepresentationMask)); 5247 __ tst(r0, Operand(kStringRepresentationMask));
5245 __ b(ne, &external_string); 5248 __ b(ne, &external_string);
5246 5249
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
6071 __ cmp(dest, Operand(limit)); 6074 __ cmp(dest, Operand(limit));
6072 __ ldrb(scratch1, MemOperand(src, 1, PostIndex), lt); 6075 __ ldrb(scratch1, MemOperand(src, 1, PostIndex), lt);
6073 __ b(ge, &done); 6076 __ b(ge, &done);
6074 __ strb(scratch1, MemOperand(dest, 1, PostIndex)); 6077 __ strb(scratch1, MemOperand(dest, 1, PostIndex));
6075 __ b(&byte_loop); 6078 __ b(&byte_loop);
6076 6079
6077 __ bind(&done); 6080 __ bind(&done);
6078 } 6081 }
6079 6082
6080 6083
6081 void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, 6084 void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm,
6082 Register c1, 6085 Register c1,
6083 Register c2, 6086 Register c2,
6084 Register scratch1, 6087 Register scratch1,
6085 Register scratch2, 6088 Register scratch2,
6086 Register scratch3, 6089 Register scratch3,
6087 Register scratch4, 6090 Register scratch4,
6088 Register scratch5, 6091 Register scratch5,
6089 Label* not_found) { 6092 Label* not_found) {
6090 // Register scratch3 is the general scratch register in this function. 6093 // Register scratch3 is the general scratch register in this function.
6091 Register scratch = scratch3; 6094 Register scratch = scratch3;
6092 6095
6093 // Make sure that both characters are not digits as such strings has a 6096 // Make sure that both characters are not digits as such strings has a
6094 // different hash algorithm. Don't try to look for these in the symbol table. 6097 // different hash algorithm. Don't try to look for these in the string table.
6095 Label not_array_index; 6098 Label not_array_index;
6096 __ sub(scratch, c1, Operand(static_cast<int>('0'))); 6099 __ sub(scratch, c1, Operand(static_cast<int>('0')));
6097 __ cmp(scratch, Operand(static_cast<int>('9' - '0'))); 6100 __ cmp(scratch, Operand(static_cast<int>('9' - '0')));
6098 __ b(hi, &not_array_index); 6101 __ b(hi, &not_array_index);
6099 __ sub(scratch, c2, Operand(static_cast<int>('0'))); 6102 __ sub(scratch, c2, Operand(static_cast<int>('0')));
6100 __ cmp(scratch, Operand(static_cast<int>('9' - '0'))); 6103 __ cmp(scratch, Operand(static_cast<int>('9' - '0')));
6101 6104
6102 // If check failed combine both characters into single halfword. 6105 // If check failed combine both characters into single halfword.
6103 // This is required by the contract of the method: code at the 6106 // This is required by the contract of the method: code at the
6104 // not_found branch expects this combination in c1 register 6107 // not_found branch expects this combination in c1 register
6105 __ orr(c1, c1, Operand(c2, LSL, kBitsPerByte), LeaveCC, ls); 6108 __ orr(c1, c1, Operand(c2, LSL, kBitsPerByte), LeaveCC, ls);
6106 __ b(ls, not_found); 6109 __ b(ls, not_found);
6107 6110
6108 __ bind(&not_array_index); 6111 __ bind(&not_array_index);
6109 // Calculate the two character string hash. 6112 // Calculate the two character string hash.
6110 Register hash = scratch1; 6113 Register hash = scratch1;
6111 StringHelper::GenerateHashInit(masm, hash, c1); 6114 StringHelper::GenerateHashInit(masm, hash, c1);
6112 StringHelper::GenerateHashAddCharacter(masm, hash, c2); 6115 StringHelper::GenerateHashAddCharacter(masm, hash, c2);
6113 StringHelper::GenerateHashGetHash(masm, hash); 6116 StringHelper::GenerateHashGetHash(masm, hash);
6114 6117
6115 // Collect the two characters in a register. 6118 // Collect the two characters in a register.
6116 Register chars = c1; 6119 Register chars = c1;
6117 __ orr(chars, chars, Operand(c2, LSL, kBitsPerByte)); 6120 __ orr(chars, chars, Operand(c2, LSL, kBitsPerByte));
6118 6121
6119 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 6122 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
6120 // hash: hash of two character string. 6123 // hash: hash of two character string.
6121 6124
6122 // Load symbol table 6125 // Load string table
6123 // Load address of first element of the symbol table. 6126 // Load address of first element of the string table.
6124 Register symbol_table = c2; 6127 Register string_table = c2;
6125 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); 6128 __ LoadRoot(string_table, Heap::kStringTableRootIndex);
6126 6129
6127 Register undefined = scratch4; 6130 Register undefined = scratch4;
6128 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); 6131 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
6129 6132
6130 // Calculate capacity mask from the symbol table capacity. 6133 // Calculate capacity mask from the string table capacity.
6131 Register mask = scratch2; 6134 Register mask = scratch2;
6132 __ ldr(mask, FieldMemOperand(symbol_table, SymbolTable::kCapacityOffset)); 6135 __ ldr(mask, FieldMemOperand(string_table, StringTable::kCapacityOffset));
6133 __ mov(mask, Operand(mask, ASR, 1)); 6136 __ mov(mask, Operand(mask, ASR, 1));
6134 __ sub(mask, mask, Operand(1)); 6137 __ sub(mask, mask, Operand(1));
6135 6138
6136 // Calculate untagged address of the first element of the symbol table. 6139 // Calculate untagged address of the first element of the string table.
6137 Register first_symbol_table_element = symbol_table; 6140 Register first_string_table_element = string_table;
6138 __ add(first_symbol_table_element, symbol_table, 6141 __ add(first_string_table_element, string_table,
6139 Operand(SymbolTable::kElementsStartOffset - kHeapObjectTag)); 6142 Operand(StringTable::kElementsStartOffset - kHeapObjectTag));
6140 6143
6141 // Registers 6144 // Registers
6142 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 6145 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
6143 // hash: hash of two character string 6146 // hash: hash of two character string
6144 // mask: capacity mask 6147 // mask: capacity mask
6145 // first_symbol_table_element: address of the first element of 6148 // first_string_table_element: address of the first element of
6146 // the symbol table 6149 // the string table
6147 // undefined: the undefined object 6150 // undefined: the undefined object
6148 // scratch: - 6151 // scratch: -
6149 6152
6150 // Perform a number of probes in the symbol table. 6153 // Perform a number of probes in the string table.
6151 const int kProbes = 4; 6154 const int kProbes = 4;
6152 Label found_in_symbol_table; 6155 Label found_in_string_table;
6153 Label next_probe[kProbes]; 6156 Label next_probe[kProbes];
6154 Register candidate = scratch5; // Scratch register contains candidate. 6157 Register candidate = scratch5; // Scratch register contains candidate.
6155 for (int i = 0; i < kProbes; i++) { 6158 for (int i = 0; i < kProbes; i++) {
6156 // Calculate entry in symbol table. 6159 // Calculate entry in string table.
6157 if (i > 0) { 6160 if (i > 0) {
6158 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); 6161 __ add(candidate, hash, Operand(StringTable::GetProbeOffset(i)));
6159 } else { 6162 } else {
6160 __ mov(candidate, hash); 6163 __ mov(candidate, hash);
6161 } 6164 }
6162 6165
6163 __ and_(candidate, candidate, Operand(mask)); 6166 __ and_(candidate, candidate, Operand(mask));
6164 6167
6165 // Load the entry from the symble table. 6168 // Load the entry from the symble table.
6166 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 6169 STATIC_ASSERT(StringTable::kEntrySize == 1);
6167 __ ldr(candidate, 6170 __ ldr(candidate,
6168 MemOperand(first_symbol_table_element, 6171 MemOperand(first_string_table_element,
6169 candidate, 6172 candidate,
6170 LSL, 6173 LSL,
6171 kPointerSizeLog2)); 6174 kPointerSizeLog2));
6172 6175
6173 // If entry is undefined no string with this hash can be found. 6176 // If entry is undefined no string with this hash can be found.
6174 Label is_string; 6177 Label is_string;
6175 __ CompareObjectType(candidate, scratch, scratch, ODDBALL_TYPE); 6178 __ CompareObjectType(candidate, scratch, scratch, ODDBALL_TYPE);
6176 __ b(ne, &is_string); 6179 __ b(ne, &is_string);
6177 6180
6178 __ cmp(undefined, candidate); 6181 __ cmp(undefined, candidate);
6179 __ b(eq, not_found); 6182 __ b(eq, not_found);
6180 // Must be the hole (deleted entry). 6183 // Must be the hole (deleted entry).
6181 if (FLAG_debug_code) { 6184 if (FLAG_debug_code) {
6182 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 6185 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
6183 __ cmp(ip, candidate); 6186 __ cmp(ip, candidate);
6184 __ Assert(eq, "oddball in symbol table is not undefined or the hole"); 6187 __ Assert(eq, "oddball in string table is not undefined or the hole");
6185 } 6188 }
6186 __ jmp(&next_probe[i]); 6189 __ jmp(&next_probe[i]);
6187 6190
6188 __ bind(&is_string); 6191 __ bind(&is_string);
6189 6192
6190 // Check that the candidate is a non-external ASCII string. The instance 6193 // Check that the candidate is a non-external ASCII string. The instance
6191 // type is still in the scratch register from the CompareObjectType 6194 // type is still in the scratch register from the CompareObjectType
6192 // operation. 6195 // operation.
6193 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]); 6196 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]);
6194 6197
6195 // If length is not 2 the string is not a candidate. 6198 // If length is not 2 the string is not a candidate.
6196 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset)); 6199 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset));
6197 __ cmp(scratch, Operand(Smi::FromInt(2))); 6200 __ cmp(scratch, Operand(Smi::FromInt(2)));
6198 __ b(ne, &next_probe[i]); 6201 __ b(ne, &next_probe[i]);
6199 6202
6200 // Check if the two characters match. 6203 // Check if the two characters match.
6201 // Assumes that word load is little endian. 6204 // Assumes that word load is little endian.
6202 __ ldrh(scratch, FieldMemOperand(candidate, SeqOneByteString::kHeaderSize)); 6205 __ ldrh(scratch, FieldMemOperand(candidate, SeqOneByteString::kHeaderSize));
6203 __ cmp(chars, scratch); 6206 __ cmp(chars, scratch);
6204 __ b(eq, &found_in_symbol_table); 6207 __ b(eq, &found_in_string_table);
6205 __ bind(&next_probe[i]); 6208 __ bind(&next_probe[i]);
6206 } 6209 }
6207 6210
6208 // No matching 2 character string found by probing. 6211 // No matching 2 character string found by probing.
6209 __ jmp(not_found); 6212 __ jmp(not_found);
6210 6213
6211 // Scratch register contains result when we fall through to here. 6214 // Scratch register contains result when we fall through to here.
6212 Register result = candidate; 6215 Register result = candidate;
6213 __ bind(&found_in_symbol_table); 6216 __ bind(&found_in_string_table);
6214 __ Move(r0, result); 6217 __ Move(r0, result);
6215 } 6218 }
6216 6219
6217 6220
6218 void StringHelper::GenerateHashInit(MacroAssembler* masm, 6221 void StringHelper::GenerateHashInit(MacroAssembler* masm,
6219 Register hash, 6222 Register hash,
6220 Register character) { 6223 Register character) {
6221 // hash = character + (character << 10); 6224 // hash = character + (character << 10);
6222 __ LoadRoot(hash, Heap::kHashSeedRootIndex); 6225 __ LoadRoot(hash, Heap::kHashSeedRootIndex);
6223 // Untag smi seed and add the character. 6226 // Untag smi seed and add the character.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
6328 // If the string is not indirect, it can only be sequential or external. 6331 // If the string is not indirect, it can only be sequential or external.
6329 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag)); 6332 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
6330 STATIC_ASSERT(kIsIndirectStringMask != 0); 6333 STATIC_ASSERT(kIsIndirectStringMask != 0);
6331 __ tst(r1, Operand(kIsIndirectStringMask)); 6334 __ tst(r1, Operand(kIsIndirectStringMask));
6332 __ b(eq, &seq_or_external_string); 6335 __ b(eq, &seq_or_external_string);
6333 6336
6334 __ tst(r1, Operand(kSlicedNotConsMask)); 6337 __ tst(r1, Operand(kSlicedNotConsMask));
6335 __ b(ne, &sliced_string); 6338 __ b(ne, &sliced_string);
6336 // Cons string. Check whether it is flat, then fetch first part. 6339 // Cons string. Check whether it is flat, then fetch first part.
6337 __ ldr(r5, FieldMemOperand(r0, ConsString::kSecondOffset)); 6340 __ ldr(r5, FieldMemOperand(r0, ConsString::kSecondOffset));
6338 __ CompareRoot(r5, Heap::kEmptyStringRootIndex); 6341 __ CompareRoot(r5, Heap::kempty_stringRootIndex);
6339 __ b(ne, &runtime); 6342 __ b(ne, &runtime);
6340 __ ldr(r5, FieldMemOperand(r0, ConsString::kFirstOffset)); 6343 __ ldr(r5, FieldMemOperand(r0, ConsString::kFirstOffset));
6341 // Update instance type. 6344 // Update instance type.
6342 __ ldr(r1, FieldMemOperand(r5, HeapObject::kMapOffset)); 6345 __ ldr(r1, FieldMemOperand(r5, HeapObject::kMapOffset));
6343 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset)); 6346 __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
6344 __ jmp(&underlying_unpacked); 6347 __ jmp(&underlying_unpacked);
6345 6348
6346 __ bind(&sliced_string); 6349 __ bind(&sliced_string);
6347 // Sliced string. Fetch parent and correct start index by offset. 6350 // Sliced string. Fetch parent and correct start index by offset.
6348 __ ldr(r5, FieldMemOperand(r0, SlicedString::kParentOffset)); 6351 __ ldr(r5, FieldMemOperand(r0, SlicedString::kParentOffset));
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
6688 // r1: second string 6691 // r1: second string
6689 // r2: length of first string 6692 // r2: length of first string
6690 // r3: length of second string 6693 // r3: length of second string
6691 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6694 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6692 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6695 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6693 // Look at the length of the result of adding the two strings. 6696 // Look at the length of the result of adding the two strings.
6694 Label string_add_flat_result, longer_than_two; 6697 Label string_add_flat_result, longer_than_two;
6695 // Adding two lengths can't overflow. 6698 // Adding two lengths can't overflow.
6696 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2); 6699 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2);
6697 __ add(r6, r2, Operand(r3)); 6700 __ add(r6, r2, Operand(r3));
6698 // Use the symbol table when adding two one character strings, as it 6701 // Use the string table when adding two one character strings, as it
6699 // helps later optimizations to return a symbol here. 6702 // helps later optimizations to return a string here.
6700 __ cmp(r6, Operand(2)); 6703 __ cmp(r6, Operand(2));
6701 __ b(ne, &longer_than_two); 6704 __ b(ne, &longer_than_two);
6702 6705
6703 // Check that both strings are non-external ASCII strings. 6706 // Check that both strings are non-external ASCII strings.
6704 if (flags_ != NO_STRING_ADD_FLAGS) { 6707 if (flags_ != NO_STRING_ADD_FLAGS) {
6705 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); 6708 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset));
6706 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); 6709 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset));
6707 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); 6710 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
6708 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); 6711 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset));
6709 } 6712 }
6710 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r7, 6713 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r4, r5, r6, r7,
6711 &call_runtime); 6714 &call_runtime);
6712 6715
6713 // Get the two characters forming the sub string. 6716 // Get the two characters forming the sub string.
6714 __ ldrb(r2, FieldMemOperand(r0, SeqOneByteString::kHeaderSize)); 6717 __ ldrb(r2, FieldMemOperand(r0, SeqOneByteString::kHeaderSize));
6715 __ ldrb(r3, FieldMemOperand(r1, SeqOneByteString::kHeaderSize)); 6718 __ ldrb(r3, FieldMemOperand(r1, SeqOneByteString::kHeaderSize));
6716 6719
6717 // Try to lookup two character string in symbol table. If it is not found 6720 // Try to lookup two character string in string table. If it is not found
6718 // just allocate a new one. 6721 // just allocate a new one.
6719 Label make_two_character_string; 6722 Label make_two_character_string;
6720 StringHelper::GenerateTwoCharacterSymbolTableProbe( 6723 StringHelper::GenerateTwoCharacterStringTableProbe(
6721 masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string); 6724 masm, r2, r3, r6, r7, r4, r5, r9, &make_two_character_string);
6722 __ IncrementCounter(counters->string_add_native(), 1, r2, r3); 6725 __ IncrementCounter(counters->string_add_native(), 1, r2, r3);
6723 __ add(sp, sp, Operand(2 * kPointerSize)); 6726 __ add(sp, sp, Operand(2 * kPointerSize));
6724 __ Ret(); 6727 __ Ret();
6725 6728
6726 __ bind(&make_two_character_string); 6729 __ bind(&make_two_character_string);
6727 // Resulting string has length 2 and first chars of two strings 6730 // Resulting string has length 2 and first chars of two strings
6728 // are combined into single halfword in r2 register. 6731 // are combined into single halfword in r2 register.
6729 // So we can fill resulting string without two loops by a single 6732 // So we can fill resulting string without two loops by a single
6730 // halfword store instruction (which assumes that processor is 6733 // halfword store instruction (which assumes that processor is
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
7051 if (Token::IsOrderedRelationalCompareOp(op_)) { 7054 if (Token::IsOrderedRelationalCompareOp(op_)) {
7052 __ CompareRoot(r1, Heap::kUndefinedValueRootIndex); 7055 __ CompareRoot(r1, Heap::kUndefinedValueRootIndex);
7053 __ b(eq, &unordered); 7056 __ b(eq, &unordered);
7054 } 7057 }
7055 7058
7056 __ bind(&miss); 7059 __ bind(&miss);
7057 GenerateMiss(masm); 7060 GenerateMiss(masm);
7058 } 7061 }
7059 7062
7060 7063
7061 void ICCompareStub::GenerateSymbols(MacroAssembler* masm) { 7064 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) {
7062 ASSERT(state_ == CompareIC::SYMBOL); 7065 ASSERT(state_ == CompareIC::INTERNALIZED_STRING);
7063 Label miss; 7066 Label miss;
7064 7067
7065 // Registers containing left and right operands respectively. 7068 // Registers containing left and right operands respectively.
7066 Register left = r1; 7069 Register left = r1;
7067 Register right = r0; 7070 Register right = r0;
7068 Register tmp1 = r2; 7071 Register tmp1 = r2;
7069 Register tmp2 = r3; 7072 Register tmp2 = r3;
7070 7073
7071 // Check that both operands are heap objects. 7074 // Check that both operands are heap objects.
7072 __ JumpIfEitherSmi(left, right, &miss); 7075 __ JumpIfEitherSmi(left, right, &miss);
7073 7076
7074 // Check that both operands are symbols. 7077 // Check that both operands are internalized strings.
7075 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); 7078 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
7076 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); 7079 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
7077 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); 7080 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
7078 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); 7081 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
7079 STATIC_ASSERT(kSymbolTag != 0); 7082 STATIC_ASSERT(kInternalizedTag != 0);
7080 __ and_(tmp1, tmp1, Operand(tmp2)); 7083 __ and_(tmp1, tmp1, Operand(tmp2));
7081 __ tst(tmp1, Operand(kIsSymbolMask)); 7084 __ tst(tmp1, Operand(kIsInternalizedMask));
7082 __ b(eq, &miss); 7085 __ b(eq, &miss);
7083 7086
7084 // Symbols are compared by identity. 7087 // Internalized strings are compared by identity.
7085 __ cmp(left, right); 7088 __ cmp(left, right);
7086 // Make sure r0 is non-zero. At this point input operands are 7089 // Make sure r0 is non-zero. At this point input operands are
7087 // guaranteed to be non-zero. 7090 // guaranteed to be non-zero.
7088 ASSERT(right.is(r0)); 7091 ASSERT(right.is(r0));
7089 STATIC_ASSERT(EQUAL == 0); 7092 STATIC_ASSERT(EQUAL == 0);
7090 STATIC_ASSERT(kSmiTag == 0); 7093 STATIC_ASSERT(kSmiTag == 0);
7091 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); 7094 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq);
7092 __ Ret(); 7095 __ Ret();
7093 7096
7094 __ bind(&miss); 7097 __ bind(&miss);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
7126 7129
7127 // Fast check for identical strings. 7130 // Fast check for identical strings.
7128 __ cmp(left, right); 7131 __ cmp(left, right);
7129 STATIC_ASSERT(EQUAL == 0); 7132 STATIC_ASSERT(EQUAL == 0);
7130 STATIC_ASSERT(kSmiTag == 0); 7133 STATIC_ASSERT(kSmiTag == 0);
7131 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); 7134 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq);
7132 __ Ret(eq); 7135 __ Ret(eq);
7133 7136
7134 // Handle not identical strings. 7137 // Handle not identical strings.
7135 7138
7136 // Check that both strings are symbols. If they are, we're done 7139 // Check that both strings are internalized strings. If they are, we're done
7137 // because we already know they are not identical. 7140 // because we already know they are not identical.
7138 if (equality) { 7141 if (equality) {
7139 ASSERT(GetCondition() == eq); 7142 ASSERT(GetCondition() == eq);
7140 STATIC_ASSERT(kSymbolTag != 0); 7143 STATIC_ASSERT(kInternalizedTag != 0);
7141 __ and_(tmp3, tmp1, Operand(tmp2)); 7144 __ and_(tmp3, tmp1, Operand(tmp2));
7142 __ tst(tmp3, Operand(kIsSymbolMask)); 7145 __ tst(tmp3, Operand(kIsInternalizedMask));
7143 // Make sure r0 is non-zero. At this point input operands are 7146 // Make sure r0 is non-zero. At this point input operands are
7144 // guaranteed to be non-zero. 7147 // guaranteed to be non-zero.
7145 ASSERT(right.is(r0)); 7148 ASSERT(right.is(r0));
7146 __ Ret(ne); 7149 __ Ret(ne);
7147 } 7150 }
7148 7151
7149 // Check that both strings are sequential ASCII. 7152 // Check that both strings are sequential ASCII.
7150 Label runtime; 7153 Label runtime;
7151 __ JumpIfBothInstanceTypesAreNotSequentialAscii( 7154 __ JumpIfBothInstanceTypesAreNotSequentialAscii(
7152 tmp1, tmp2, tmp3, tmp4, &runtime); 7155 tmp1, tmp2, tmp3, tmp4, &runtime);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
7314 __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex); 7317 __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex);
7315 7318
7316 // Stop if found the property. 7319 // Stop if found the property.
7317 __ cmp(entity_name, Operand(Handle<String>(name))); 7320 __ cmp(entity_name, Operand(Handle<String>(name)));
7318 __ b(eq, miss); 7321 __ b(eq, miss);
7319 7322
7320 Label the_hole; 7323 Label the_hole;
7321 __ cmp(entity_name, tmp); 7324 __ cmp(entity_name, tmp);
7322 __ b(eq, &the_hole); 7325 __ b(eq, &the_hole);
7323 7326
7324 // Check if the entry name is not a symbol. 7327 // Check if the entry name is not an internalized string.
7325 __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); 7328 __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset));
7326 __ ldrb(entity_name, 7329 __ ldrb(entity_name,
7327 FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); 7330 FieldMemOperand(entity_name, Map::kInstanceTypeOffset));
7328 __ tst(entity_name, Operand(kIsSymbolMask)); 7331 __ tst(entity_name, Operand(kIsInternalizedMask));
7329 __ b(eq, miss); 7332 __ b(eq, miss);
7330 7333
7331 __ bind(&the_hole); 7334 __ bind(&the_hole);
7332 7335
7333 // Restore the properties. 7336 // Restore the properties.
7334 __ ldr(properties, 7337 __ ldr(properties,
7335 FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 7338 FieldMemOperand(receiver, JSObject::kPropertiesOffset));
7336 } 7339 }
7337 } 7340 }
7338 7341
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
7487 7490
7488 // Having undefined at this place means the name is not contained. 7491 // Having undefined at this place means the name is not contained.
7489 __ cmp(entry_key, Operand(undefined)); 7492 __ cmp(entry_key, Operand(undefined));
7490 __ b(eq, &not_in_dictionary); 7493 __ b(eq, &not_in_dictionary);
7491 7494
7492 // Stop if found the property. 7495 // Stop if found the property.
7493 __ cmp(entry_key, Operand(key)); 7496 __ cmp(entry_key, Operand(key));
7494 __ b(eq, &in_dictionary); 7497 __ b(eq, &in_dictionary);
7495 7498
7496 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 7499 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
7497 // Check if the entry name is not a symbol. 7500 // Check if the entry name is not an internalized string.
7498 __ ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset)); 7501 __ ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset));
7499 __ ldrb(entry_key, 7502 __ ldrb(entry_key,
7500 FieldMemOperand(entry_key, Map::kInstanceTypeOffset)); 7503 FieldMemOperand(entry_key, Map::kInstanceTypeOffset));
7501 __ tst(entry_key, Operand(kIsSymbolMask)); 7504 __ tst(entry_key, Operand(kIsInternalizedMask));
7502 __ b(eq, &maybe_in_dictionary); 7505 __ b(eq, &maybe_in_dictionary);
7503 } 7506 }
7504 } 7507 }
7505 7508
7506 __ bind(&maybe_in_dictionary); 7509 __ bind(&maybe_in_dictionary);
7507 // If we are doing negative lookup then probing failure should be 7510 // If we are doing negative lookup then probing failure should be
7508 // treated as a lookup success. For positive lookup probing failure 7511 // treated as a lookup success. For positive lookup probing failure
7509 // should be treated as lookup failure. 7512 // should be treated as lookup failure.
7510 if (mode_ == POSITIVE_LOOKUP) { 7513 if (mode_ == POSITIVE_LOOKUP) {
7511 __ mov(result, Operand::Zero()); 7514 __ mov(result, Operand::Zero());
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
7946 7949
7947 __ Pop(lr, r5, r1); 7950 __ Pop(lr, r5, r1);
7948 __ Ret(); 7951 __ Ret();
7949 } 7952 }
7950 7953
7951 #undef __ 7954 #undef __
7952 7955
7953 } } // namespace v8::internal 7956 } } // namespace v8::internal
7954 7957
7955 #endif // V8_TARGET_ARCH_ARM 7958 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698