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 17895002: The check for internalized strings relied on the fact that we had less (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More comments Created 7 years, 5 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 | src/arm/ic-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 874 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 885
886 __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE); 886 __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE);
887 __ b(ge, &return_not_equal); 887 __ b(ge, &return_not_equal);
888 888
889 // Check for oddballs: true, false, null, undefined. 889 // Check for oddballs: true, false, null, undefined.
890 __ cmp(r3, Operand(ODDBALL_TYPE)); 890 __ cmp(r3, Operand(ODDBALL_TYPE));
891 __ b(eq, &return_not_equal); 891 __ b(eq, &return_not_equal);
892 892
893 // Now that we have the types we might as well check for 893 // Now that we have the types we might as well check for
894 // internalized-internalized. 894 // internalized-internalized.
895 // Ensure that no non-strings have the internalized bit set. 895 Label not_internalized;
896 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsInternalizedMask);
897 STATIC_ASSERT(kInternalizedTag != 0); 896 STATIC_ASSERT(kInternalizedTag != 0);
898 __ and_(r2, r2, Operand(r3)); 897 __ and_(r2, r2, Operand(kIsNotStringMask | kIsInternalizedMask));
899 __ tst(r2, Operand(kIsInternalizedMask)); 898 __ cmp(r2, Operand(kInternalizedTag | kStringTag));
900 __ b(ne, &return_not_equal); 899 __ b(ne, &not_internalized); // r2 (rhs) is not an internalized string
900
901 __ and_(r3, r3, Operand(kIsNotStringMask | kIsInternalizedMask));
902 __ cmp(r3, Operand(kInternalizedTag | kStringTag));
903 __ b(eq, &return_not_equal); // both rhs and lhs are internalized strings
904
905 __ bind(&not_internalized);
901 } 906 }
902 907
903 908
904 // See comment at call site. 909 // See comment at call site.
905 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, 910 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm,
906 Register lhs, 911 Register lhs,
907 Register rhs, 912 Register rhs,
908 Label* both_loaded_as_doubles, 913 Label* both_loaded_as_doubles,
909 Label* not_heap_numbers, 914 Label* not_heap_numbers,
910 Label* slow) { 915 Label* slow) {
(...skipping 19 matching lines...) Expand all
930 // Fast negative check for internalized-to-internalized equality. 935 // Fast negative check for internalized-to-internalized equality.
931 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm, 936 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
932 Register lhs, 937 Register lhs,
933 Register rhs, 938 Register rhs,
934 Label* possible_strings, 939 Label* possible_strings,
935 Label* not_both_strings) { 940 Label* not_both_strings) {
936 ASSERT((lhs.is(r0) && rhs.is(r1)) || 941 ASSERT((lhs.is(r0) && rhs.is(r1)) ||
937 (lhs.is(r1) && rhs.is(r0))); 942 (lhs.is(r1) && rhs.is(r0)));
938 943
939 // r2 is object type of rhs. 944 // r2 is object type of rhs.
940 // Ensure that no non-strings have the internalized bit set.
941 Label object_test; 945 Label object_test;
942 STATIC_ASSERT(kInternalizedTag != 0); 946 STATIC_ASSERT(kInternalizedTag != 0);
943 __ tst(r2, Operand(kIsNotStringMask)); 947 __ tst(r2, Operand(kIsNotStringMask));
944 __ b(ne, &object_test); 948 __ b(ne, &object_test);
945 __ tst(r2, Operand(kIsInternalizedMask)); 949 __ tst(r2, Operand(kIsInternalizedMask));
946 __ b(eq, possible_strings); 950 __ b(eq, possible_strings);
947 __ CompareObjectType(lhs, r3, r3, FIRST_NONSTRING_TYPE); 951 __ CompareObjectType(lhs, r3, r3, FIRST_NONSTRING_TYPE);
948 __ b(ge, not_both_strings); 952 __ b(ge, not_both_strings);
949 __ tst(r3, Operand(kIsInternalizedMask)); 953 __ tst(r3, Operand(kIsInternalizedMask));
950 __ b(eq, possible_strings); 954 __ b(eq, possible_strings);
(...skipping 5255 matching lines...) Expand 10 before | Expand all | Expand 10 after
6206 6210
6207 // Check that both operands are heap objects. 6211 // Check that both operands are heap objects.
6208 __ JumpIfEitherSmi(left, right, &miss); 6212 __ JumpIfEitherSmi(left, right, &miss);
6209 6213
6210 // Check that both operands are internalized strings. 6214 // Check that both operands are internalized strings.
6211 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); 6215 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
6212 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); 6216 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
6213 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); 6217 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
6214 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); 6218 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
6215 STATIC_ASSERT(kInternalizedTag != 0); 6219 STATIC_ASSERT(kInternalizedTag != 0);
6216 __ and_(tmp1, tmp1, Operand(tmp2)); 6220
6217 __ tst(tmp1, Operand(kIsInternalizedMask)); 6221 __ and_(tmp1, tmp1, Operand(kIsNotStringMask | kIsInternalizedMask));
6218 __ b(eq, &miss); 6222 __ cmp(tmp1, Operand(kInternalizedTag | kStringTag));
6223 __ b(ne, &miss);
6224
6225 __ and_(tmp2, tmp2, Operand(kIsNotStringMask | kIsInternalizedMask));
6226 __ cmp(tmp2, Operand(kInternalizedTag | kStringTag));
6227 __ b(ne, &miss);
6219 6228
6220 // Internalized strings are compared by identity. 6229 // Internalized strings are compared by identity.
6221 __ cmp(left, right); 6230 __ cmp(left, right);
6222 // Make sure r0 is non-zero. At this point input operands are 6231 // Make sure r0 is non-zero. At this point input operands are
6223 // guaranteed to be non-zero. 6232 // guaranteed to be non-zero.
6224 ASSERT(right.is(r0)); 6233 ASSERT(right.is(r0));
6225 STATIC_ASSERT(EQUAL == 0); 6234 STATIC_ASSERT(EQUAL == 0);
6226 STATIC_ASSERT(kSmiTag == 0); 6235 STATIC_ASSERT(kSmiTag == 0);
6227 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); 6236 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq);
6228 __ Ret(); 6237 __ Ret();
(...skipping 18 matching lines...) Expand all
6247 __ JumpIfEitherSmi(left, right, &miss); 6256 __ JumpIfEitherSmi(left, right, &miss);
6248 6257
6249 // Check that both operands are unique names. This leaves the instance 6258 // Check that both operands are unique names. This leaves the instance
6250 // types loaded in tmp1 and tmp2. 6259 // types loaded in tmp1 and tmp2.
6251 STATIC_ASSERT(kInternalizedTag != 0); 6260 STATIC_ASSERT(kInternalizedTag != 0);
6252 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); 6261 __ ldr(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
6253 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); 6262 __ ldr(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
6254 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); 6263 __ ldrb(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
6255 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); 6264 __ ldrb(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
6256 6265
6257 Label succeed1; 6266 __ JumpIfNotUniqueName(tmp1, &miss);
6258 __ tst(tmp1, Operand(kIsInternalizedMask)); 6267 __ JumpIfNotUniqueName(tmp2, &miss);
6259 __ b(ne, &succeed1);
6260 __ cmp(tmp1, Operand(SYMBOL_TYPE));
6261 __ b(ne, &miss);
6262 __ bind(&succeed1);
6263
6264 Label succeed2;
6265 __ tst(tmp2, Operand(kIsInternalizedMask));
6266 __ b(ne, &succeed2);
6267 __ cmp(tmp2, Operand(SYMBOL_TYPE));
6268 __ b(ne, &miss);
6269 __ bind(&succeed2);
6270 6268
6271 // Unique names are compared by identity. 6269 // Unique names are compared by identity.
6272 __ cmp(left, right); 6270 __ cmp(left, right);
6273 // Make sure r0 is non-zero. At this point input operands are 6271 // Make sure r0 is non-zero. At this point input operands are
6274 // guaranteed to be non-zero. 6272 // guaranteed to be non-zero.
6275 ASSERT(right.is(r0)); 6273 ASSERT(right.is(r0));
6276 STATIC_ASSERT(EQUAL == 0); 6274 STATIC_ASSERT(EQUAL == 0);
6277 STATIC_ASSERT(kSmiTag == 0); 6275 STATIC_ASSERT(kSmiTag == 0);
6278 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); 6276 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq);
6279 __ Ret(); 6277 __ Ret();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6314 // Fast check for identical strings. 6312 // Fast check for identical strings.
6315 __ cmp(left, right); 6313 __ cmp(left, right);
6316 STATIC_ASSERT(EQUAL == 0); 6314 STATIC_ASSERT(EQUAL == 0);
6317 STATIC_ASSERT(kSmiTag == 0); 6315 STATIC_ASSERT(kSmiTag == 0);
6318 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq); 6316 __ mov(r0, Operand(Smi::FromInt(EQUAL)), LeaveCC, eq);
6319 __ Ret(eq); 6317 __ Ret(eq);
6320 6318
6321 // Handle not identical strings. 6319 // Handle not identical strings.
6322 6320
6323 // Check that both strings are internalized strings. If they are, we're done 6321 // Check that both strings are internalized strings. If they are, we're done
6324 // because we already know they are not identical. 6322 // because we already know they are not identical. We know they are both
6323 // strings.
6325 if (equality) { 6324 if (equality) {
6326 ASSERT(GetCondition() == eq); 6325 ASSERT(GetCondition() == eq);
6327 STATIC_ASSERT(kInternalizedTag != 0); 6326 STATIC_ASSERT(kInternalizedTag != 0);
6328 __ and_(tmp3, tmp1, Operand(tmp2)); 6327 __ and_(tmp3, tmp1, Operand(tmp2));
6329 __ tst(tmp3, Operand(kIsInternalizedMask)); 6328 __ tst(tmp3, Operand(kIsInternalizedMask));
6330 // Make sure r0 is non-zero. At this point input operands are 6329 // Make sure r0 is non-zero. At this point input operands are
6331 // guaranteed to be non-zero. 6330 // guaranteed to be non-zero.
6332 ASSERT(right.is(r0)); 6331 ASSERT(right.is(r0));
6333 __ Ret(ne); 6332 __ Ret(ne);
6334 } 6333 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
6500 __ b(eq, miss); 6499 __ b(eq, miss);
6501 6500
6502 Label good; 6501 Label good;
6503 __ cmp(entity_name, tmp); 6502 __ cmp(entity_name, tmp);
6504 __ b(eq, &good); 6503 __ b(eq, &good);
6505 6504
6506 // Check if the entry name is not a unique name. 6505 // Check if the entry name is not a unique name.
6507 __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); 6506 __ ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset));
6508 __ ldrb(entity_name, 6507 __ ldrb(entity_name,
6509 FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); 6508 FieldMemOperand(entity_name, Map::kInstanceTypeOffset));
6510 __ tst(entity_name, Operand(kIsInternalizedMask)); 6509 __ JumpIfNotUniqueName(entity_name, miss);
6511 __ b(ne, &good);
6512 __ cmp(entity_name, Operand(SYMBOL_TYPE));
6513 __ b(ne, miss);
6514
6515 __ bind(&good); 6510 __ bind(&good);
6516 6511
6517 // Restore the properties. 6512 // Restore the properties.
6518 __ ldr(properties, 6513 __ ldr(properties,
6519 FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 6514 FieldMemOperand(receiver, JSObject::kPropertiesOffset));
6520 } 6515 }
6521 6516
6522 const int spill_mask = 6517 const int spill_mask =
6523 (lr.bit() | r6.bit() | r5.bit() | r4.bit() | r3.bit() | 6518 (lr.bit() | r6.bit() | r5.bit() | r4.bit() | r3.bit() |
6524 r2.bit() | r1.bit() | r0.bit()); 6519 r2.bit() | r1.bit() | r0.bit());
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
6671 // Having undefined at this place means the name is not contained. 6666 // Having undefined at this place means the name is not contained.
6672 __ cmp(entry_key, Operand(undefined)); 6667 __ cmp(entry_key, Operand(undefined));
6673 __ b(eq, &not_in_dictionary); 6668 __ b(eq, &not_in_dictionary);
6674 6669
6675 // Stop if found the property. 6670 // Stop if found the property.
6676 __ cmp(entry_key, Operand(key)); 6671 __ cmp(entry_key, Operand(key));
6677 __ b(eq, &in_dictionary); 6672 __ b(eq, &in_dictionary);
6678 6673
6679 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 6674 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
6680 // Check if the entry name is not a unique name. 6675 // Check if the entry name is not a unique name.
6681 Label cont;
6682 __ ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset)); 6676 __ ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset));
6683 __ ldrb(entry_key, 6677 __ ldrb(entry_key,
6684 FieldMemOperand(entry_key, Map::kInstanceTypeOffset)); 6678 FieldMemOperand(entry_key, Map::kInstanceTypeOffset));
6685 __ tst(entry_key, Operand(kIsInternalizedMask)); 6679 __ JumpIfNotUniqueName(entry_key, &maybe_in_dictionary);
6686 __ b(ne, &cont);
6687 __ cmp(entry_key, Operand(SYMBOL_TYPE));
6688 __ b(ne, &maybe_in_dictionary);
6689 __ bind(&cont);
6690 } 6680 }
6691 } 6681 }
6692 6682
6693 __ bind(&maybe_in_dictionary); 6683 __ bind(&maybe_in_dictionary);
6694 // If we are doing negative lookup then probing failure should be 6684 // If we are doing negative lookup then probing failure should be
6695 // treated as a lookup success. For positive lookup probing failure 6685 // treated as a lookup success. For positive lookup probing failure
6696 // should be treated as lookup failure. 6686 // should be treated as lookup failure.
6697 if (mode_ == POSITIVE_LOOKUP) { 6687 if (mode_ == POSITIVE_LOOKUP) {
6698 __ mov(result, Operand::Zero()); 6688 __ mov(result, Operand::Zero());
6699 __ Ret(); 6689 __ Ret();
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after
7411 __ bind(&fast_elements_case); 7401 __ bind(&fast_elements_case);
7412 GenerateCase(masm, FAST_ELEMENTS); 7402 GenerateCase(masm, FAST_ELEMENTS);
7413 } 7403 }
7414 7404
7415 7405
7416 #undef __ 7406 #undef __
7417 7407
7418 } } // namespace v8::internal 7408 } } // namespace v8::internal
7419 7409
7420 #endif // V8_TARGET_ARCH_ARM 7410 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698