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

Side by Side Diff: src/ia32/code-stubs-ia32.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/ia32/code-stubs-ia32.h ('k') | src/ia32/full-codegen-ia32.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 3263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3274 3274
3275 void ArrayLengthStub::Generate(MacroAssembler* masm) { 3275 void ArrayLengthStub::Generate(MacroAssembler* masm) {
3276 // ----------- S t a t e ------------- 3276 // ----------- S t a t e -------------
3277 // -- ecx : name 3277 // -- ecx : name
3278 // -- edx : receiver 3278 // -- edx : receiver
3279 // -- esp[0] : return address 3279 // -- esp[0] : return address
3280 // ----------------------------------- 3280 // -----------------------------------
3281 Label miss; 3281 Label miss;
3282 3282
3283 if (kind() == Code::KEYED_LOAD_IC) { 3283 if (kind() == Code::KEYED_LOAD_IC) {
3284 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_symbol())); 3284 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_string()));
3285 __ j(not_equal, &miss); 3285 __ j(not_equal, &miss);
3286 } 3286 }
3287 3287
3288 StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss); 3288 StubCompiler::GenerateLoadArrayLength(masm, edx, eax, &miss);
3289 __ bind(&miss); 3289 __ bind(&miss);
3290 StubCompiler::GenerateLoadMiss(masm, kind()); 3290 StubCompiler::GenerateLoadMiss(masm, kind());
3291 } 3291 }
3292 3292
3293 3293
3294 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 3294 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
3295 // ----------- S t a t e ------------- 3295 // ----------- S t a t e -------------
3296 // -- ecx : name 3296 // -- ecx : name
3297 // -- edx : receiver 3297 // -- edx : receiver
3298 // -- esp[0] : return address 3298 // -- esp[0] : return address
3299 // ----------------------------------- 3299 // -----------------------------------
3300 Label miss; 3300 Label miss;
3301 3301
3302 if (kind() == Code::KEYED_LOAD_IC) { 3302 if (kind() == Code::KEYED_LOAD_IC) {
3303 __ cmp(ecx, Immediate(masm->isolate()->factory()->prototype_symbol())); 3303 __ cmp(ecx, Immediate(masm->isolate()->factory()->prototype_string()));
3304 __ j(not_equal, &miss); 3304 __ j(not_equal, &miss);
3305 } 3305 }
3306 3306
3307 StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss); 3307 StubCompiler::GenerateLoadFunctionPrototype(masm, edx, eax, ebx, &miss);
3308 __ bind(&miss); 3308 __ bind(&miss);
3309 StubCompiler::GenerateLoadMiss(masm, kind()); 3309 StubCompiler::GenerateLoadMiss(masm, kind());
3310 } 3310 }
3311 3311
3312 3312
3313 void StringLengthStub::Generate(MacroAssembler* masm) { 3313 void StringLengthStub::Generate(MacroAssembler* masm) {
3314 // ----------- S t a t e ------------- 3314 // ----------- S t a t e -------------
3315 // -- ecx : name 3315 // -- ecx : name
3316 // -- edx : receiver 3316 // -- edx : receiver
3317 // -- esp[0] : return address 3317 // -- esp[0] : return address
3318 // ----------------------------------- 3318 // -----------------------------------
3319 Label miss; 3319 Label miss;
3320 3320
3321 if (kind() == Code::KEYED_LOAD_IC) { 3321 if (kind() == Code::KEYED_LOAD_IC) {
3322 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_symbol())); 3322 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_string()));
3323 __ j(not_equal, &miss); 3323 __ j(not_equal, &miss);
3324 } 3324 }
3325 3325
3326 StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss, 3326 StubCompiler::GenerateLoadStringLength(masm, edx, eax, ebx, &miss,
3327 support_wrapper_); 3327 support_wrapper_);
3328 __ bind(&miss); 3328 __ bind(&miss);
3329 StubCompiler::GenerateLoadMiss(masm, kind()); 3329 StubCompiler::GenerateLoadMiss(masm, kind());
3330 } 3330 }
3331 3331
3332 3332
(...skipping 10 matching lines...) Expand all
3343 // elements of FixedArray type). Value must be a number, but only smis are 3343 // elements of FixedArray type). Value must be a number, but only smis are
3344 // accepted as the most common case. 3344 // accepted as the most common case.
3345 3345
3346 Label miss; 3346 Label miss;
3347 3347
3348 Register receiver = edx; 3348 Register receiver = edx;
3349 Register value = eax; 3349 Register value = eax;
3350 Register scratch = ebx; 3350 Register scratch = ebx;
3351 3351
3352 if (kind() == Code::KEYED_LOAD_IC) { 3352 if (kind() == Code::KEYED_LOAD_IC) {
3353 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_symbol())); 3353 __ cmp(ecx, Immediate(masm->isolate()->factory()->length_string()));
3354 __ j(not_equal, &miss); 3354 __ j(not_equal, &miss);
3355 } 3355 }
3356 3356
3357 // Check that the receiver isn't a smi. 3357 // Check that the receiver isn't a smi.
3358 __ JumpIfSmi(receiver, &miss); 3358 __ JumpIfSmi(receiver, &miss);
3359 3359
3360 // Check that the object is a JS array. 3360 // Check that the object is a JS array.
3361 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); 3361 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
3362 __ j(not_equal, &miss); 3362 __ j(not_equal, &miss);
3363 3363
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after
4433 Label* fail) { 4433 Label* fail) {
4434 Label ok; 4434 Label ok;
4435 if (expected == CompareIC::SMI) { 4435 if (expected == CompareIC::SMI) {
4436 __ JumpIfNotSmi(input, fail); 4436 __ JumpIfNotSmi(input, fail);
4437 } else if (expected == CompareIC::HEAP_NUMBER) { 4437 } else if (expected == CompareIC::HEAP_NUMBER) {
4438 __ JumpIfSmi(input, &ok); 4438 __ JumpIfSmi(input, &ok);
4439 __ cmp(FieldOperand(input, HeapObject::kMapOffset), 4439 __ cmp(FieldOperand(input, HeapObject::kMapOffset),
4440 Immediate(masm->isolate()->factory()->heap_number_map())); 4440 Immediate(masm->isolate()->factory()->heap_number_map()));
4441 __ j(not_equal, fail); 4441 __ j(not_equal, fail);
4442 } 4442 }
4443 // We could be strict about symbol/string here, but as long as 4443 // We could be strict about internalized/non-internalized here, but as long as
4444 // hydrogen doesn't care, the stub doesn't have to care either. 4444 // hydrogen doesn't care, the stub doesn't have to care either.
4445 __ bind(&ok); 4445 __ bind(&ok);
4446 } 4446 }
4447 4447
4448 4448
4449 static void BranchIfNonSymbol(MacroAssembler* masm, 4449 static void BranchIfNotInternalizedString(MacroAssembler* masm,
4450 Label* label, 4450 Label* label,
4451 Register object, 4451 Register object,
4452 Register scratch) { 4452 Register scratch) {
4453 __ JumpIfSmi(object, label); 4453 __ JumpIfSmi(object, label);
4454 __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset)); 4454 __ mov(scratch, FieldOperand(object, HeapObject::kMapOffset));
4455 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 4455 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
4456 __ and_(scratch, kIsSymbolMask | kIsNotStringMask); 4456 __ and_(scratch, kIsInternalizedMask | kIsNotStringMask);
4457 __ cmp(scratch, kSymbolTag | kStringTag); 4457 __ cmp(scratch, kInternalizedTag | kStringTag);
4458 __ j(not_equal, label); 4458 __ j(not_equal, label);
4459 } 4459 }
4460 4460
4461 4461
4462 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { 4462 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
4463 Label check_unequal_objects; 4463 Label check_unequal_objects;
4464 Condition cc = GetCondition(); 4464 Condition cc = GetCondition();
4465 4465
4466 Label miss; 4466 Label miss;
4467 CheckInputType(masm, edx, left_, &miss); 4467 CheckInputType(masm, edx, left_, &miss);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
4675 if (cc == less || cc == less_equal) { 4675 if (cc == less || cc == less_equal) {
4676 __ mov(eax, Immediate(Smi::FromInt(1))); 4676 __ mov(eax, Immediate(Smi::FromInt(1)));
4677 } else { 4677 } else {
4678 __ mov(eax, Immediate(Smi::FromInt(-1))); 4678 __ mov(eax, Immediate(Smi::FromInt(-1)));
4679 } 4679 }
4680 __ ret(0); 4680 __ ret(0);
4681 4681
4682 // The number comparison code did not provide a valid result. 4682 // The number comparison code did not provide a valid result.
4683 __ bind(&non_number_comparison); 4683 __ bind(&non_number_comparison);
4684 4684
4685 // Fast negative check for symbol-to-symbol equality. 4685 // Fast negative check for internalized-to-internalized equality.
4686 Label check_for_strings; 4686 Label check_for_strings;
4687 if (cc == equal) { 4687 if (cc == equal) {
4688 BranchIfNonSymbol(masm, &check_for_strings, eax, ecx); 4688 BranchIfNotInternalizedString(masm, &check_for_strings, eax, ecx);
4689 BranchIfNonSymbol(masm, &check_for_strings, edx, ecx); 4689 BranchIfNotInternalizedString(masm, &check_for_strings, edx, ecx);
4690 4690
4691 // We've already checked for object identity, so if both operands 4691 // We've already checked for object identity, so if both operands
4692 // are symbols they aren't equal. Register eax already holds a 4692 // are internalized they aren't equal. Register eax already holds a
4693 // non-zero value, which indicates not equal, so just return. 4693 // non-zero value, which indicates not equal, so just return.
4694 __ ret(0); 4694 __ ret(0);
4695 } 4695 }
4696 4696
4697 __ bind(&check_for_strings); 4697 __ bind(&check_for_strings);
4698 4698
4699 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, 4699 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx,
4700 &check_unequal_objects); 4700 &check_unequal_objects);
4701 4701
4702 // Inline comparison of ASCII strings. 4702 // Inline comparison of ASCII strings.
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after
5763 // ebx: length of first string as a smi 5763 // ebx: length of first string as a smi
5764 // ecx: length of second string as a smi 5764 // ecx: length of second string as a smi
5765 // edx: second string 5765 // edx: second string
5766 // Look at the length of the result of adding the two strings. 5766 // Look at the length of the result of adding the two strings.
5767 Label string_add_flat_result, longer_than_two; 5767 Label string_add_flat_result, longer_than_two;
5768 __ bind(&both_not_zero_length); 5768 __ bind(&both_not_zero_length);
5769 __ add(ebx, ecx); 5769 __ add(ebx, ecx);
5770 STATIC_ASSERT(Smi::kMaxValue == String::kMaxLength); 5770 STATIC_ASSERT(Smi::kMaxValue == String::kMaxLength);
5771 // Handle exceptionally long strings in the runtime system. 5771 // Handle exceptionally long strings in the runtime system.
5772 __ j(overflow, &call_runtime); 5772 __ j(overflow, &call_runtime);
5773 // Use the symbol table when adding two one character strings, as it 5773 // Use the string table when adding two one character strings, as it
5774 // helps later optimizations to return a symbol here. 5774 // helps later optimizations to return an internalized string here.
5775 __ cmp(ebx, Immediate(Smi::FromInt(2))); 5775 __ cmp(ebx, Immediate(Smi::FromInt(2)));
5776 __ j(not_equal, &longer_than_two); 5776 __ j(not_equal, &longer_than_two);
5777 5777
5778 // Check that both strings are non-external ASCII strings. 5778 // Check that both strings are non-external ASCII strings.
5779 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, &call_runtime); 5779 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, &call_runtime);
5780 5780
5781 // Get the two characters forming the new string. 5781 // Get the two characters forming the new string.
5782 __ movzx_b(ebx, FieldOperand(eax, SeqOneByteString::kHeaderSize)); 5782 __ movzx_b(ebx, FieldOperand(eax, SeqOneByteString::kHeaderSize));
5783 __ movzx_b(ecx, FieldOperand(edx, SeqOneByteString::kHeaderSize)); 5783 __ movzx_b(ecx, FieldOperand(edx, SeqOneByteString::kHeaderSize));
5784 5784
5785 // Try to lookup two character string in symbol table. If it is not found 5785 // Try to lookup two character string in string table. If it is not found
5786 // just allocate a new one. 5786 // just allocate a new one.
5787 Label make_two_character_string, make_two_character_string_no_reload; 5787 Label make_two_character_string, make_two_character_string_no_reload;
5788 StringHelper::GenerateTwoCharacterSymbolTableProbe( 5788 StringHelper::GenerateTwoCharacterStringTableProbe(
5789 masm, ebx, ecx, eax, edx, edi, 5789 masm, ebx, ecx, eax, edx, edi,
5790 &make_two_character_string_no_reload, &make_two_character_string); 5790 &make_two_character_string_no_reload, &make_two_character_string);
5791 __ IncrementCounter(counters->string_add_native(), 1); 5791 __ IncrementCounter(counters->string_add_native(), 1);
5792 __ ret(2 * kPointerSize); 5792 __ ret(2 * kPointerSize);
5793 5793
5794 // Allocate a two character string. 5794 // Allocate a two character string.
5795 __ bind(&make_two_character_string); 5795 __ bind(&make_two_character_string);
5796 // Reload the arguments. 5796 // Reload the arguments.
5797 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument. 5797 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
5798 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument. 5798 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
6124 __ mov_b(Operand(dest, 0), scratch); 6124 __ mov_b(Operand(dest, 0), scratch);
6125 __ add(src, Immediate(1)); 6125 __ add(src, Immediate(1));
6126 __ add(dest, Immediate(1)); 6126 __ add(dest, Immediate(1));
6127 __ sub(count, Immediate(1)); 6127 __ sub(count, Immediate(1));
6128 __ j(not_zero, &loop); 6128 __ j(not_zero, &loop);
6129 6129
6130 __ bind(&done); 6130 __ bind(&done);
6131 } 6131 }
6132 6132
6133 6133
6134 void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, 6134 void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm,
6135 Register c1, 6135 Register c1,
6136 Register c2, 6136 Register c2,
6137 Register scratch1, 6137 Register scratch1,
6138 Register scratch2, 6138 Register scratch2,
6139 Register scratch3, 6139 Register scratch3,
6140 Label* not_probed, 6140 Label* not_probed,
6141 Label* not_found) { 6141 Label* not_found) {
6142 // Register scratch3 is the general scratch register in this function. 6142 // Register scratch3 is the general scratch register in this function.
6143 Register scratch = scratch3; 6143 Register scratch = scratch3;
6144 6144
6145 // Make sure that both characters are not digits as such strings has a 6145 // Make sure that both characters are not digits as such strings has a
6146 // different hash algorithm. Don't try to look for these in the symbol table. 6146 // different hash algorithm. Don't try to look for these in the string table.
6147 Label not_array_index; 6147 Label not_array_index;
6148 __ mov(scratch, c1); 6148 __ mov(scratch, c1);
6149 __ sub(scratch, Immediate(static_cast<int>('0'))); 6149 __ sub(scratch, Immediate(static_cast<int>('0')));
6150 __ cmp(scratch, Immediate(static_cast<int>('9' - '0'))); 6150 __ cmp(scratch, Immediate(static_cast<int>('9' - '0')));
6151 __ j(above, &not_array_index, Label::kNear); 6151 __ j(above, &not_array_index, Label::kNear);
6152 __ mov(scratch, c2); 6152 __ mov(scratch, c2);
6153 __ sub(scratch, Immediate(static_cast<int>('0'))); 6153 __ sub(scratch, Immediate(static_cast<int>('0')));
6154 __ cmp(scratch, Immediate(static_cast<int>('9' - '0'))); 6154 __ cmp(scratch, Immediate(static_cast<int>('9' - '0')));
6155 __ j(below_equal, not_probed); 6155 __ j(below_equal, not_probed);
6156 6156
6157 __ bind(&not_array_index); 6157 __ bind(&not_array_index);
6158 // Calculate the two character string hash. 6158 // Calculate the two character string hash.
6159 Register hash = scratch1; 6159 Register hash = scratch1;
6160 GenerateHashInit(masm, hash, c1, scratch); 6160 GenerateHashInit(masm, hash, c1, scratch);
6161 GenerateHashAddCharacter(masm, hash, c2, scratch); 6161 GenerateHashAddCharacter(masm, hash, c2, scratch);
6162 GenerateHashGetHash(masm, hash, scratch); 6162 GenerateHashGetHash(masm, hash, scratch);
6163 6163
6164 // Collect the two characters in a register. 6164 // Collect the two characters in a register.
6165 Register chars = c1; 6165 Register chars = c1;
6166 __ shl(c2, kBitsPerByte); 6166 __ shl(c2, kBitsPerByte);
6167 __ or_(chars, c2); 6167 __ or_(chars, c2);
6168 6168
6169 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 6169 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
6170 // hash: hash of two character string. 6170 // hash: hash of two character string.
6171 6171
6172 // Load the symbol table. 6172 // Load the string table.
6173 Register symbol_table = c2; 6173 Register string_table = c2;
6174 ExternalReference roots_array_start = 6174 ExternalReference roots_array_start =
6175 ExternalReference::roots_array_start(masm->isolate()); 6175 ExternalReference::roots_array_start(masm->isolate());
6176 __ mov(scratch, Immediate(Heap::kSymbolTableRootIndex)); 6176 __ mov(scratch, Immediate(Heap::kStringTableRootIndex));
6177 __ mov(symbol_table, 6177 __ mov(string_table,
6178 Operand::StaticArray(scratch, times_pointer_size, roots_array_start)); 6178 Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
6179 6179
6180 // Calculate capacity mask from the symbol table capacity. 6180 // Calculate capacity mask from the string table capacity.
6181 Register mask = scratch2; 6181 Register mask = scratch2;
6182 __ mov(mask, FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); 6182 __ mov(mask, FieldOperand(string_table, StringTable::kCapacityOffset));
6183 __ SmiUntag(mask); 6183 __ SmiUntag(mask);
6184 __ sub(mask, Immediate(1)); 6184 __ sub(mask, Immediate(1));
6185 6185
6186 // Registers 6186 // Registers
6187 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 6187 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
6188 // hash: hash of two character string 6188 // hash: hash of two character string
6189 // symbol_table: symbol table 6189 // string_table: string table
6190 // mask: capacity mask 6190 // mask: capacity mask
6191 // scratch: - 6191 // scratch: -
6192 6192
6193 // Perform a number of probes in the symbol table. 6193 // Perform a number of probes in the string table.
6194 static const int kProbes = 4; 6194 static const int kProbes = 4;
6195 Label found_in_symbol_table; 6195 Label found_in_string_table;
6196 Label next_probe[kProbes], next_probe_pop_mask[kProbes]; 6196 Label next_probe[kProbes], next_probe_pop_mask[kProbes];
6197 Register candidate = scratch; // Scratch register contains candidate. 6197 Register candidate = scratch; // Scratch register contains candidate.
6198 for (int i = 0; i < kProbes; i++) { 6198 for (int i = 0; i < kProbes; i++) {
6199 // Calculate entry in symbol table. 6199 // Calculate entry in string table.
6200 __ mov(scratch, hash); 6200 __ mov(scratch, hash);
6201 if (i > 0) { 6201 if (i > 0) {
6202 __ add(scratch, Immediate(SymbolTable::GetProbeOffset(i))); 6202 __ add(scratch, Immediate(StringTable::GetProbeOffset(i)));
6203 } 6203 }
6204 __ and_(scratch, mask); 6204 __ and_(scratch, mask);
6205 6205
6206 // Load the entry from the symbol table. 6206 // Load the entry from the string table.
6207 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 6207 STATIC_ASSERT(StringTable::kEntrySize == 1);
6208 __ mov(candidate, 6208 __ mov(candidate,
6209 FieldOperand(symbol_table, 6209 FieldOperand(string_table,
6210 scratch, 6210 scratch,
6211 times_pointer_size, 6211 times_pointer_size,
6212 SymbolTable::kElementsStartOffset)); 6212 StringTable::kElementsStartOffset));
6213 6213
6214 // If entry is undefined no string with this hash can be found. 6214 // If entry is undefined no string with this hash can be found.
6215 Factory* factory = masm->isolate()->factory(); 6215 Factory* factory = masm->isolate()->factory();
6216 __ cmp(candidate, factory->undefined_value()); 6216 __ cmp(candidate, factory->undefined_value());
6217 __ j(equal, not_found); 6217 __ j(equal, not_found);
6218 __ cmp(candidate, factory->the_hole_value()); 6218 __ cmp(candidate, factory->the_hole_value());
6219 __ j(equal, &next_probe[i]); 6219 __ j(equal, &next_probe[i]);
6220 6220
6221 // If length is not 2 the string is not a candidate. 6221 // If length is not 2 the string is not a candidate.
6222 __ cmp(FieldOperand(candidate, String::kLengthOffset), 6222 __ cmp(FieldOperand(candidate, String::kLengthOffset),
6223 Immediate(Smi::FromInt(2))); 6223 Immediate(Smi::FromInt(2)));
6224 __ j(not_equal, &next_probe[i]); 6224 __ j(not_equal, &next_probe[i]);
6225 6225
6226 // As we are out of registers save the mask on the stack and use that 6226 // As we are out of registers save the mask on the stack and use that
6227 // register as a temporary. 6227 // register as a temporary.
6228 __ push(mask); 6228 __ push(mask);
6229 Register temp = mask; 6229 Register temp = mask;
6230 6230
6231 // Check that the candidate is a non-external ASCII string. 6231 // Check that the candidate is a non-external ASCII string.
6232 __ mov(temp, FieldOperand(candidate, HeapObject::kMapOffset)); 6232 __ mov(temp, FieldOperand(candidate, HeapObject::kMapOffset));
6233 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); 6233 __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
6234 __ JumpIfInstanceTypeIsNotSequentialAscii( 6234 __ JumpIfInstanceTypeIsNotSequentialAscii(
6235 temp, temp, &next_probe_pop_mask[i]); 6235 temp, temp, &next_probe_pop_mask[i]);
6236 6236
6237 // Check if the two characters match. 6237 // Check if the two characters match.
6238 __ mov(temp, FieldOperand(candidate, SeqOneByteString::kHeaderSize)); 6238 __ mov(temp, FieldOperand(candidate, SeqOneByteString::kHeaderSize));
6239 __ and_(temp, 0x0000ffff); 6239 __ and_(temp, 0x0000ffff);
6240 __ cmp(chars, temp); 6240 __ cmp(chars, temp);
6241 __ j(equal, &found_in_symbol_table); 6241 __ j(equal, &found_in_string_table);
6242 __ bind(&next_probe_pop_mask[i]); 6242 __ bind(&next_probe_pop_mask[i]);
6243 __ pop(mask); 6243 __ pop(mask);
6244 __ bind(&next_probe[i]); 6244 __ bind(&next_probe[i]);
6245 } 6245 }
6246 6246
6247 // No matching 2 character string found by probing. 6247 // No matching 2 character string found by probing.
6248 __ jmp(not_found); 6248 __ jmp(not_found);
6249 6249
6250 // Scratch register contains result when we fall through to here. 6250 // Scratch register contains result when we fall through to here.
6251 Register result = candidate; 6251 Register result = candidate;
6252 __ bind(&found_in_symbol_table); 6252 __ bind(&found_in_string_table);
6253 __ pop(mask); // Pop saved mask from the stack. 6253 __ pop(mask); // Pop saved mask from the stack.
6254 if (!result.is(eax)) { 6254 if (!result.is(eax)) {
6255 __ mov(eax, result); 6255 __ mov(eax, result);
6256 } 6256 }
6257 } 6257 }
6258 6258
6259 6259
6260 void StringHelper::GenerateHashInit(MacroAssembler* masm, 6260 void StringHelper::GenerateHashInit(MacroAssembler* masm,
6261 Register hash, 6261 Register hash,
6262 Register character, 6262 Register character,
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
6840 if (Token::IsOrderedRelationalCompareOp(op_)) { 6840 if (Token::IsOrderedRelationalCompareOp(op_)) {
6841 __ cmp(edx, Immediate(masm->isolate()->factory()->undefined_value())); 6841 __ cmp(edx, Immediate(masm->isolate()->factory()->undefined_value()));
6842 __ j(equal, &unordered); 6842 __ j(equal, &unordered);
6843 } 6843 }
6844 6844
6845 __ bind(&miss); 6845 __ bind(&miss);
6846 GenerateMiss(masm); 6846 GenerateMiss(masm);
6847 } 6847 }
6848 6848
6849 6849
6850 void ICCompareStub::GenerateSymbols(MacroAssembler* masm) { 6850 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) {
6851 ASSERT(state_ == CompareIC::SYMBOL); 6851 ASSERT(state_ == CompareIC::INTERNALIZED_STRING);
6852 ASSERT(GetCondition() == equal); 6852 ASSERT(GetCondition() == equal);
6853 6853
6854 // Registers containing left and right operands respectively. 6854 // Registers containing left and right operands respectively.
6855 Register left = edx; 6855 Register left = edx;
6856 Register right = eax; 6856 Register right = eax;
6857 Register tmp1 = ecx; 6857 Register tmp1 = ecx;
6858 Register tmp2 = ebx; 6858 Register tmp2 = ebx;
6859 6859
6860 // Check that both operands are heap objects. 6860 // Check that both operands are heap objects.
6861 Label miss; 6861 Label miss;
6862 __ mov(tmp1, left); 6862 __ mov(tmp1, left);
6863 STATIC_ASSERT(kSmiTag == 0); 6863 STATIC_ASSERT(kSmiTag == 0);
6864 __ and_(tmp1, right); 6864 __ and_(tmp1, right);
6865 __ JumpIfSmi(tmp1, &miss, Label::kNear); 6865 __ JumpIfSmi(tmp1, &miss, Label::kNear);
6866 6866
6867 // Check that both operands are symbols. 6867 // Check that both operands are internalized strings.
6868 __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset)); 6868 __ mov(tmp1, FieldOperand(left, HeapObject::kMapOffset));
6869 __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset)); 6869 __ mov(tmp2, FieldOperand(right, HeapObject::kMapOffset));
6870 __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); 6870 __ movzx_b(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
6871 __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); 6871 __ movzx_b(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset));
6872 STATIC_ASSERT(kSymbolTag != 0); 6872 STATIC_ASSERT(kInternalizedTag != 0);
6873 __ and_(tmp1, tmp2); 6873 __ and_(tmp1, tmp2);
6874 __ test(tmp1, Immediate(kIsSymbolMask)); 6874 __ test(tmp1, Immediate(kIsInternalizedMask));
6875 __ j(zero, &miss, Label::kNear); 6875 __ j(zero, &miss, Label::kNear);
6876 6876
6877 // Symbols are compared by identity. 6877 // Internalized strings are compared by identity.
6878 Label done; 6878 Label done;
6879 __ cmp(left, right); 6879 __ cmp(left, right);
6880 // Make sure eax is non-zero. At this point input operands are 6880 // Make sure eax is non-zero. At this point input operands are
6881 // guaranteed to be non-zero. 6881 // guaranteed to be non-zero.
6882 ASSERT(right.is(eax)); 6882 ASSERT(right.is(eax));
6883 __ j(not_equal, &done, Label::kNear); 6883 __ j(not_equal, &done, Label::kNear);
6884 STATIC_ASSERT(EQUAL == 0); 6884 STATIC_ASSERT(EQUAL == 0);
6885 STATIC_ASSERT(kSmiTag == 0); 6885 STATIC_ASSERT(kSmiTag == 0);
6886 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 6886 __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
6887 __ bind(&done); 6887 __ bind(&done);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
6928 __ cmp(left, right); 6928 __ cmp(left, right);
6929 __ j(not_equal, &not_same, Label::kNear); 6929 __ j(not_equal, &not_same, Label::kNear);
6930 STATIC_ASSERT(EQUAL == 0); 6930 STATIC_ASSERT(EQUAL == 0);
6931 STATIC_ASSERT(kSmiTag == 0); 6931 STATIC_ASSERT(kSmiTag == 0);
6932 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); 6932 __ Set(eax, Immediate(Smi::FromInt(EQUAL)));
6933 __ ret(0); 6933 __ ret(0);
6934 6934
6935 // Handle not identical strings. 6935 // Handle not identical strings.
6936 __ bind(&not_same); 6936 __ bind(&not_same);
6937 6937
6938 // Check that both strings are symbols. If they are, we're done 6938 // Check that both strings are internalized. If they are, we're done
6939 // because we already know they are not identical. But in the case of 6939 // because we already know they are not identical. But in the case of
6940 // non-equality compare, we still need to determine the order. 6940 // non-equality compare, we still need to determine the order.
6941 if (equality) { 6941 if (equality) {
6942 Label do_compare; 6942 Label do_compare;
6943 STATIC_ASSERT(kSymbolTag != 0); 6943 STATIC_ASSERT(kInternalizedTag != 0);
6944 __ and_(tmp1, tmp2); 6944 __ and_(tmp1, tmp2);
6945 __ test(tmp1, Immediate(kIsSymbolMask)); 6945 __ test(tmp1, Immediate(kIsInternalizedMask));
6946 __ j(zero, &do_compare, Label::kNear); 6946 __ j(zero, &do_compare, Label::kNear);
6947 // Make sure eax is non-zero. At this point input operands are 6947 // Make sure eax is non-zero. At this point input operands are
6948 // guaranteed to be non-zero. 6948 // guaranteed to be non-zero.
6949 ASSERT(right.is(eax)); 6949 ASSERT(right.is(eax));
6950 __ ret(0); 6950 __ ret(0);
6951 __ bind(&do_compare); 6951 __ bind(&do_compare);
6952 } 6952 }
6953 6953
6954 // Check that both strings are sequential ASCII. 6954 // Check that both strings are sequential ASCII.
6955 Label runtime; 6955 Label runtime;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
7043 7043
7044 // Do a tail call to the rewritten stub. 7044 // Do a tail call to the rewritten stub.
7045 __ jmp(edi); 7045 __ jmp(edi);
7046 } 7046 }
7047 7047
7048 7048
7049 // Helper function used to check that the dictionary doesn't contain 7049 // Helper function used to check that the dictionary doesn't contain
7050 // the property. This function may return false negatives, so miss_label 7050 // the property. This function may return false negatives, so miss_label
7051 // must always call a backup property check that is complete. 7051 // must always call a backup property check that is complete.
7052 // This function is safe to call if the receiver has fast properties. 7052 // This function is safe to call if the receiver has fast properties.
7053 // Name must be a symbol and receiver must be a heap object. 7053 // Name must be an internalized string and receiver must be a heap object.
7054 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, 7054 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
7055 Label* miss, 7055 Label* miss,
7056 Label* done, 7056 Label* done,
7057 Register properties, 7057 Register properties,
7058 Handle<String> name, 7058 Handle<String> name,
7059 Register r0) { 7059 Register r0) {
7060 ASSERT(name->IsSymbol()); 7060 ASSERT(name->IsInternalizedString());
7061 7061
7062 // If names of slots in range from 1 to kProbes - 1 for the hash value are 7062 // If names of slots in range from 1 to kProbes - 1 for the hash value are
7063 // not equal to the name and kProbes-th slot is not used (its name is the 7063 // not equal to the name and kProbes-th slot is not used (its name is the
7064 // undefined value), it guarantees the hash table doesn't contain the 7064 // undefined value), it guarantees the hash table doesn't contain the
7065 // property. It's true even if some slots represent deleted properties 7065 // property. It's true even if some slots represent deleted properties
7066 // (their names are the hole value). 7066 // (their names are the hole value).
7067 for (int i = 0; i < kInlinedProbes; i++) { 7067 for (int i = 0; i < kInlinedProbes; i++) {
7068 // Compute the masked index: (hash + i + i * i) & mask. 7068 // Compute the masked index: (hash + i + i * i) & mask.
7069 Register index = r0; 7069 Register index = r0;
7070 // Capacity is smi 2^n. 7070 // Capacity is smi 2^n.
(...skipping 16 matching lines...) Expand all
7087 7087
7088 // Stop if found the property. 7088 // Stop if found the property.
7089 __ cmp(entity_name, Handle<String>(name)); 7089 __ cmp(entity_name, Handle<String>(name));
7090 __ j(equal, miss); 7090 __ j(equal, miss);
7091 7091
7092 Label the_hole; 7092 Label the_hole;
7093 // Check for the hole and skip. 7093 // Check for the hole and skip.
7094 __ cmp(entity_name, masm->isolate()->factory()->the_hole_value()); 7094 __ cmp(entity_name, masm->isolate()->factory()->the_hole_value());
7095 __ j(equal, &the_hole, Label::kNear); 7095 __ j(equal, &the_hole, Label::kNear);
7096 7096
7097 // Check if the entry name is not a symbol. 7097 // Check if the entry name is not an internalized string.
7098 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); 7098 __ mov(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
7099 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset), 7099 __ test_b(FieldOperand(entity_name, Map::kInstanceTypeOffset),
7100 kIsSymbolMask); 7100 kIsInternalizedMask);
7101 __ j(zero, miss); 7101 __ j(zero, miss);
7102 __ bind(&the_hole); 7102 __ bind(&the_hole);
7103 } 7103 }
7104 7104
7105 StringDictionaryLookupStub stub(properties, 7105 StringDictionaryLookupStub stub(properties,
7106 r0, 7106 r0,
7107 r0, 7107 r0,
7108 StringDictionaryLookupStub::NEGATIVE_LOOKUP); 7108 StringDictionaryLookupStub::NEGATIVE_LOOKUP);
7109 __ push(Immediate(Handle<Object>(name))); 7109 __ push(Immediate(Handle<Object>(name)));
7110 __ push(Immediate(name->Hash())); 7110 __ push(Immediate(name->Hash()));
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
7225 times_pointer_size, 7225 times_pointer_size,
7226 kElementsStartOffset - kHeapObjectTag)); 7226 kElementsStartOffset - kHeapObjectTag));
7227 __ cmp(scratch, masm->isolate()->factory()->undefined_value()); 7227 __ cmp(scratch, masm->isolate()->factory()->undefined_value());
7228 __ j(equal, &not_in_dictionary); 7228 __ j(equal, &not_in_dictionary);
7229 7229
7230 // Stop if found the property. 7230 // Stop if found the property.
7231 __ cmp(scratch, Operand(esp, 3 * kPointerSize)); 7231 __ cmp(scratch, Operand(esp, 3 * kPointerSize));
7232 __ j(equal, &in_dictionary); 7232 __ j(equal, &in_dictionary);
7233 7233
7234 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 7234 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
7235 // If we hit a non symbol key during negative lookup 7235 // If we hit a key that is not an internalized string during negative
7236 // we have to bailout as this key might be equal to the 7236 // lookup we have to bailout as this key might be equal to the
7237 // key we are looking for. 7237 // key we are looking for.
7238 7238
7239 // Check if the entry name is not a symbol. 7239 // Check if the entry name is not an internalized string.
7240 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 7240 __ mov(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
7241 __ test_b(FieldOperand(scratch, Map::kInstanceTypeOffset), 7241 __ test_b(FieldOperand(scratch, Map::kInstanceTypeOffset),
7242 kIsSymbolMask); 7242 kIsInternalizedMask);
7243 __ j(zero, &maybe_in_dictionary); 7243 __ j(zero, &maybe_in_dictionary);
7244 } 7244 }
7245 } 7245 }
7246 7246
7247 __ bind(&maybe_in_dictionary); 7247 __ bind(&maybe_in_dictionary);
7248 // If we are doing negative lookup then probing failure should be 7248 // If we are doing negative lookup then probing failure should be
7249 // treated as a lookup success. For positive lookup probing failure 7249 // treated as a lookup success. For positive lookup probing failure
7250 // should be treated as lookup failure. 7250 // should be treated as lookup failure.
7251 if (mode_ == POSITIVE_LOOKUP) { 7251 if (mode_ == POSITIVE_LOOKUP) {
7252 __ mov(result_, Immediate(0)); 7252 __ mov(result_, Immediate(0));
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
7687 // Restore ecx. 7687 // Restore ecx.
7688 __ pop(ecx); 7688 __ pop(ecx);
7689 __ ret(0); 7689 __ ret(0);
7690 } 7690 }
7691 7691
7692 #undef __ 7692 #undef __
7693 7693
7694 } } // namespace v8::internal 7694 } } // namespace v8::internal
7695 7695
7696 #endif // V8_TARGET_ARCH_IA32 7696 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698