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

Side by Side Diff: src/x64/code-stubs-x64.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/x64/code-stubs-x64.h ('k') | src/x64/codegen-x64.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 2364 matching lines...) Expand 10 before | Expand all | Expand 10 after
2375 2375
2376 void ArrayLengthStub::Generate(MacroAssembler* masm) { 2376 void ArrayLengthStub::Generate(MacroAssembler* masm) {
2377 Label miss; 2377 Label miss;
2378 Register receiver; 2378 Register receiver;
2379 if (kind() == Code::KEYED_LOAD_IC) { 2379 if (kind() == Code::KEYED_LOAD_IC) {
2380 // ----------- S t a t e ------------- 2380 // ----------- S t a t e -------------
2381 // -- rax : key 2381 // -- rax : key
2382 // -- rdx : receiver 2382 // -- rdx : receiver
2383 // -- rsp[0] : return address 2383 // -- rsp[0] : return address
2384 // ----------------------------------- 2384 // -----------------------------------
2385 __ Cmp(rax, masm->isolate()->factory()->length_symbol()); 2385 __ Cmp(rax, masm->isolate()->factory()->length_string());
2386 receiver = rdx; 2386 receiver = rdx;
2387 } else { 2387 } else {
2388 ASSERT(kind() == Code::LOAD_IC); 2388 ASSERT(kind() == Code::LOAD_IC);
2389 // ----------- S t a t e ------------- 2389 // ----------- S t a t e -------------
2390 // -- rax : receiver 2390 // -- rax : receiver
2391 // -- rcx : name 2391 // -- rcx : name
2392 // -- rsp[0] : return address 2392 // -- rsp[0] : return address
2393 // ----------------------------------- 2393 // -----------------------------------
2394 receiver = rax; 2394 receiver = rax;
2395 } 2395 }
2396 2396
2397 StubCompiler::GenerateLoadArrayLength(masm, receiver, r8, &miss); 2397 StubCompiler::GenerateLoadArrayLength(masm, receiver, r8, &miss);
2398 __ bind(&miss); 2398 __ bind(&miss);
2399 StubCompiler::GenerateLoadMiss(masm, kind()); 2399 StubCompiler::GenerateLoadMiss(masm, kind());
2400 } 2400 }
2401 2401
2402 2402
2403 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { 2403 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
2404 Label miss; 2404 Label miss;
2405 Register receiver; 2405 Register receiver;
2406 if (kind() == Code::KEYED_LOAD_IC) { 2406 if (kind() == Code::KEYED_LOAD_IC) {
2407 // ----------- S t a t e ------------- 2407 // ----------- S t a t e -------------
2408 // -- rax : key 2408 // -- rax : key
2409 // -- rdx : receiver 2409 // -- rdx : receiver
2410 // -- rsp[0] : return address 2410 // -- rsp[0] : return address
2411 // ----------------------------------- 2411 // -----------------------------------
2412 __ Cmp(rax, masm->isolate()->factory()->prototype_symbol()); 2412 __ Cmp(rax, masm->isolate()->factory()->prototype_string());
2413 receiver = rdx; 2413 receiver = rdx;
2414 } else { 2414 } else {
2415 ASSERT(kind() == Code::LOAD_IC); 2415 ASSERT(kind() == Code::LOAD_IC);
2416 // ----------- S t a t e ------------- 2416 // ----------- S t a t e -------------
2417 // -- rax : receiver 2417 // -- rax : receiver
2418 // -- rcx : name 2418 // -- rcx : name
2419 // -- rsp[0] : return address 2419 // -- rsp[0] : return address
2420 // ----------------------------------- 2420 // -----------------------------------
2421 receiver = rax; 2421 receiver = rax;
2422 } 2422 }
2423 2423
2424 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, r9, &miss); 2424 StubCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8, r9, &miss);
2425 __ bind(&miss); 2425 __ bind(&miss);
2426 StubCompiler::GenerateLoadMiss(masm, kind()); 2426 StubCompiler::GenerateLoadMiss(masm, kind());
2427 } 2427 }
2428 2428
2429 2429
2430 void StringLengthStub::Generate(MacroAssembler* masm) { 2430 void StringLengthStub::Generate(MacroAssembler* masm) {
2431 Label miss; 2431 Label miss;
2432 Register receiver; 2432 Register receiver;
2433 if (kind() == Code::KEYED_LOAD_IC) { 2433 if (kind() == Code::KEYED_LOAD_IC) {
2434 // ----------- S t a t e ------------- 2434 // ----------- S t a t e -------------
2435 // -- rax : key 2435 // -- rax : key
2436 // -- rdx : receiver 2436 // -- rdx : receiver
2437 // -- rsp[0] : return address 2437 // -- rsp[0] : return address
2438 // ----------------------------------- 2438 // -----------------------------------
2439 __ Cmp(rax, masm->isolate()->factory()->length_symbol()); 2439 __ Cmp(rax, masm->isolate()->factory()->length_string());
2440 receiver = rdx; 2440 receiver = rdx;
2441 } else { 2441 } else {
2442 ASSERT(kind() == Code::LOAD_IC); 2442 ASSERT(kind() == Code::LOAD_IC);
2443 // ----------- S t a t e ------------- 2443 // ----------- S t a t e -------------
2444 // -- rax : receiver 2444 // -- rax : receiver
2445 // -- rcx : name 2445 // -- rcx : name
2446 // -- rsp[0] : return address 2446 // -- rsp[0] : return address
2447 // ----------------------------------- 2447 // -----------------------------------
2448 receiver = rax; 2448 receiver = rax;
2449 } 2449 }
(...skipping 17 matching lines...) Expand all
2467 // (currently anything except for external arrays which means anything with 2467 // (currently anything except for external arrays which means anything with
2468 // elements of FixedArray type). Value must be a number, but only smis are 2468 // elements of FixedArray type). Value must be a number, but only smis are
2469 // accepted as the most common case. 2469 // accepted as the most common case.
2470 2470
2471 Label miss; 2471 Label miss;
2472 2472
2473 Register receiver = rdx; 2473 Register receiver = rdx;
2474 Register value = rax; 2474 Register value = rax;
2475 Register scratch = rbx; 2475 Register scratch = rbx;
2476 if (kind() == Code::KEYED_STORE_IC) { 2476 if (kind() == Code::KEYED_STORE_IC) {
2477 __ Cmp(rcx, masm->isolate()->factory()->length_symbol()); 2477 __ Cmp(rcx, masm->isolate()->factory()->length_string());
2478 } 2478 }
2479 2479
2480 // Check that the receiver isn't a smi. 2480 // Check that the receiver isn't a smi.
2481 __ JumpIfSmi(receiver, &miss); 2481 __ JumpIfSmi(receiver, &miss);
2482 2482
2483 // Check that the object is a JS array. 2483 // Check that the object is a JS array.
2484 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); 2484 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
2485 __ j(not_equal, &miss); 2485 __ j(not_equal, &miss);
2486 2486
2487 // Check that elements are FixedArray. 2487 // Check that elements are FixedArray.
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
3070 // String is sliced. 3070 // String is sliced.
3071 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset)); 3071 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset));
3072 __ movq(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); 3072 __ movq(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
3073 // r14: slice offset 3073 // r14: slice offset
3074 // r15: original subject string 3074 // r15: original subject string
3075 // rdi: parent string 3075 // rdi: parent string
3076 __ jmp(&check_encoding, Label::kNear); 3076 __ jmp(&check_encoding, Label::kNear);
3077 // String is a cons string, check whether it is flat. 3077 // String is a cons string, check whether it is flat.
3078 __ bind(&cons_string); 3078 __ bind(&cons_string);
3079 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset), 3079 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset),
3080 Heap::kEmptyStringRootIndex); 3080 Heap::kempty_stringRootIndex);
3081 __ j(not_equal, &runtime); 3081 __ j(not_equal, &runtime);
3082 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset)); 3082 __ movq(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
3083 // rdi: first part of cons string or parent of sliced string. 3083 // rdi: first part of cons string or parent of sliced string.
3084 // rbx: map of first part of cons string or map of parent of sliced string. 3084 // rbx: map of first part of cons string or map of parent of sliced string.
3085 // Is first part of cons or parent of slice a flat two byte string? 3085 // Is first part of cons or parent of slice a flat two byte string?
3086 __ bind(&check_encoding); 3086 __ bind(&check_encoding);
3087 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 3087 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
3088 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset), 3088 __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
3089 Immediate(kStringRepresentationMask | kStringEncodingMask)); 3089 Immediate(kStringRepresentationMask | kStringEncodingMask));
3090 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 3090 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
3569 CompareIC::State expected, 3569 CompareIC::State expected,
3570 Label* fail) { 3570 Label* fail) {
3571 Label ok; 3571 Label ok;
3572 if (expected == CompareIC::SMI) { 3572 if (expected == CompareIC::SMI) {
3573 __ JumpIfNotSmi(input, fail); 3573 __ JumpIfNotSmi(input, fail);
3574 } else if (expected == CompareIC::HEAP_NUMBER) { 3574 } else if (expected == CompareIC::HEAP_NUMBER) {
3575 __ JumpIfSmi(input, &ok); 3575 __ JumpIfSmi(input, &ok);
3576 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL); 3576 __ CompareMap(input, masm->isolate()->factory()->heap_number_map(), NULL);
3577 __ j(not_equal, fail); 3577 __ j(not_equal, fail);
3578 } 3578 }
3579 // We could be strict about symbol/string here, but as long as 3579 // We could be strict about internalized/non-internalized here, but as long as
3580 // hydrogen doesn't care, the stub doesn't have to care either. 3580 // hydrogen doesn't care, the stub doesn't have to care either.
3581 __ bind(&ok); 3581 __ bind(&ok);
3582 } 3582 }
3583 3583
3584 3584
3585 static void BranchIfNonSymbol(MacroAssembler* masm, 3585 static void BranchIfNotInternalizedString(MacroAssembler* masm,
3586 Label* label, 3586 Label* label,
3587 Register object, 3587 Register object,
3588 Register scratch) { 3588 Register scratch) {
3589 __ JumpIfSmi(object, label); 3589 __ JumpIfSmi(object, label);
3590 __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset)); 3590 __ movq(scratch, FieldOperand(object, HeapObject::kMapOffset));
3591 __ movzxbq(scratch, 3591 __ movzxbq(scratch,
3592 FieldOperand(scratch, Map::kInstanceTypeOffset)); 3592 FieldOperand(scratch, Map::kInstanceTypeOffset));
3593 // Ensure that no non-strings have the symbol bit set. 3593 // Ensure that no non-strings have the internalized bit set.
3594 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsSymbolMask); 3594 STATIC_ASSERT(LAST_TYPE < kNotStringTag + kIsInternalizedMask);
3595 STATIC_ASSERT(kSymbolTag != 0); 3595 STATIC_ASSERT(kInternalizedTag != 0);
3596 __ testb(scratch, Immediate(kIsSymbolMask)); 3596 __ testb(scratch, Immediate(kIsInternalizedMask));
3597 __ j(zero, label); 3597 __ j(zero, label);
3598 } 3598 }
3599 3599
3600 3600
3601 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) { 3601 void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
3602 Label check_unequal_objects, done; 3602 Label check_unequal_objects, done;
3603 Condition cc = GetCondition(); 3603 Condition cc = GetCondition();
3604 Factory* factory = masm->isolate()->factory(); 3604 Factory* factory = masm->isolate()->factory();
3605 3605
3606 Label miss; 3606 Label miss;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
3754 if (cc == less || cc == less_equal) { 3754 if (cc == less || cc == less_equal) {
3755 __ Set(rax, 1); 3755 __ Set(rax, 1);
3756 } else { 3756 } else {
3757 __ Set(rax, -1); 3757 __ Set(rax, -1);
3758 } 3758 }
3759 __ ret(0); 3759 __ ret(0);
3760 3760
3761 // The number comparison code did not provide a valid result. 3761 // The number comparison code did not provide a valid result.
3762 __ bind(&non_number_comparison); 3762 __ bind(&non_number_comparison);
3763 3763
3764 // Fast negative check for symbol-to-symbol equality. 3764 // Fast negative check for internalized-to-internalized equality.
3765 Label check_for_strings; 3765 Label check_for_strings;
3766 if (cc == equal) { 3766 if (cc == equal) {
3767 BranchIfNonSymbol(masm, &check_for_strings, rax, kScratchRegister); 3767 BranchIfNotInternalizedString(
3768 BranchIfNonSymbol(masm, &check_for_strings, rdx, kScratchRegister); 3768 masm, &check_for_strings, rax, kScratchRegister);
3769 BranchIfNotInternalizedString(
3770 masm, &check_for_strings, rdx, kScratchRegister);
3769 3771
3770 // We've already checked for object identity, so if both operands 3772 // We've already checked for object identity, so if both operands are
3771 // are symbols they aren't equal. Register eax (not rax) already holds a 3773 // internalized strings they aren't equal. Register eax (not rax) already
3772 // non-zero value, which indicates not equal, so just return. 3774 // holds a non-zero value, which indicates not equal, so just return.
3773 __ ret(0); 3775 __ ret(0);
3774 } 3776 }
3775 3777
3776 __ bind(&check_for_strings); 3778 __ bind(&check_for_strings);
3777 3779
3778 __ JumpIfNotBothSequentialAsciiStrings( 3780 __ JumpIfNotBothSequentialAsciiStrings(
3779 rdx, rax, rcx, rbx, &check_unequal_objects); 3781 rdx, rax, rcx, rbx, &check_unequal_objects);
3780 3782
3781 // Inline comparison of ASCII strings. 3783 // Inline comparison of ASCII strings.
3782 if (cc == equal) { 3784 if (cc == equal) {
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after
4846 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset)); 4848 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset));
4847 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); 4849 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
4848 } 4850 }
4849 // Get the instance types of the two strings as they will be needed soon. 4851 // Get the instance types of the two strings as they will be needed soon.
4850 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset)); 4852 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset));
4851 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); 4853 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
4852 4854
4853 // Look at the length of the result of adding the two strings. 4855 // Look at the length of the result of adding the two strings.
4854 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2); 4856 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
4855 __ SmiAdd(rbx, rbx, rcx); 4857 __ SmiAdd(rbx, rbx, rcx);
4856 // Use the symbol table when adding two one character strings, as it 4858 // Use the string table when adding two one character strings, as it
4857 // helps later optimizations to return a symbol here. 4859 // helps later optimizations to return an internalized string here.
4858 __ SmiCompare(rbx, Smi::FromInt(2)); 4860 __ SmiCompare(rbx, Smi::FromInt(2));
4859 __ j(not_equal, &longer_than_two); 4861 __ j(not_equal, &longer_than_two);
4860 4862
4861 // Check that both strings are non-external ASCII strings. 4863 // Check that both strings are non-external ASCII strings.
4862 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, 4864 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx,
4863 &call_runtime); 4865 &call_runtime);
4864 4866
4865 // Get the two characters forming the sub string. 4867 // Get the two characters forming the sub string.
4866 __ movzxbq(rbx, FieldOperand(rax, SeqOneByteString::kHeaderSize)); 4868 __ movzxbq(rbx, FieldOperand(rax, SeqOneByteString::kHeaderSize));
4867 __ movzxbq(rcx, FieldOperand(rdx, SeqOneByteString::kHeaderSize)); 4869 __ movzxbq(rcx, FieldOperand(rdx, SeqOneByteString::kHeaderSize));
4868 4870
4869 // Try to lookup two character string in symbol table. If it is not found 4871 // Try to lookup two character string in string table. If it is not found
4870 // just allocate a new one. 4872 // just allocate a new one.
4871 Label make_two_character_string, make_flat_ascii_string; 4873 Label make_two_character_string, make_flat_ascii_string;
4872 StringHelper::GenerateTwoCharacterSymbolTableProbe( 4874 StringHelper::GenerateTwoCharacterStringTableProbe(
4873 masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string); 4875 masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string);
4874 __ IncrementCounter(counters->string_add_native(), 1); 4876 __ IncrementCounter(counters->string_add_native(), 1);
4875 __ ret(2 * kPointerSize); 4877 __ ret(2 * kPointerSize);
4876 4878
4877 __ bind(&make_two_character_string); 4879 __ bind(&make_two_character_string);
4878 __ Set(rdi, 2); 4880 __ Set(rdi, 2);
4879 __ AllocateAsciiString(rax, rdi, r8, r9, r11, &call_runtime); 4881 __ AllocateAsciiString(rax, rdi, r8, r9, r11, &call_runtime);
4880 // rbx - first byte: first character 4882 // rbx - first byte: first character
4881 // rbx - second byte: *maybe* second character 4883 // rbx - second byte: *maybe* second character
4882 // Make sure that the second byte of rbx contains the second character. 4884 // Make sure that the second byte of rbx contains the second character.
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
5161 __ movb(kScratchRegister, Operand(src, 0)); 5163 __ movb(kScratchRegister, Operand(src, 0));
5162 __ movb(Operand(dest, 0), kScratchRegister); 5164 __ movb(Operand(dest, 0), kScratchRegister);
5163 __ incq(src); 5165 __ incq(src);
5164 __ incq(dest); 5166 __ incq(dest);
5165 __ decl(count); 5167 __ decl(count);
5166 __ j(not_zero, &loop); 5168 __ j(not_zero, &loop);
5167 5169
5168 __ bind(&done); 5170 __ bind(&done);
5169 } 5171 }
5170 5172
5171 void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, 5173 void StringHelper::GenerateTwoCharacterStringTableProbe(MacroAssembler* masm,
5172 Register c1, 5174 Register c1,
5173 Register c2, 5175 Register c2,
5174 Register scratch1, 5176 Register scratch1,
5175 Register scratch2, 5177 Register scratch2,
5176 Register scratch3, 5178 Register scratch3,
5177 Register scratch4, 5179 Register scratch4,
5178 Label* not_found) { 5180 Label* not_found) {
5179 // Register scratch3 is the general scratch register in this function. 5181 // Register scratch3 is the general scratch register in this function.
5180 Register scratch = scratch3; 5182 Register scratch = scratch3;
5181 5183
5182 // Make sure that both characters are not digits as such strings has a 5184 // Make sure that both characters are not digits as such strings has a
5183 // different hash algorithm. Don't try to look for these in the symbol table. 5185 // different hash algorithm. Don't try to look for these in the string table.
5184 Label not_array_index; 5186 Label not_array_index;
5185 __ leal(scratch, Operand(c1, -'0')); 5187 __ leal(scratch, Operand(c1, -'0'));
5186 __ cmpl(scratch, Immediate(static_cast<int>('9' - '0'))); 5188 __ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
5187 __ j(above, &not_array_index, Label::kNear); 5189 __ j(above, &not_array_index, Label::kNear);
5188 __ leal(scratch, Operand(c2, -'0')); 5190 __ leal(scratch, Operand(c2, -'0'));
5189 __ cmpl(scratch, Immediate(static_cast<int>('9' - '0'))); 5191 __ cmpl(scratch, Immediate(static_cast<int>('9' - '0')));
5190 __ j(below_equal, not_found); 5192 __ j(below_equal, not_found);
5191 5193
5192 __ bind(&not_array_index); 5194 __ bind(&not_array_index);
5193 // Calculate the two character string hash. 5195 // Calculate the two character string hash.
5194 Register hash = scratch1; 5196 Register hash = scratch1;
5195 GenerateHashInit(masm, hash, c1, scratch); 5197 GenerateHashInit(masm, hash, c1, scratch);
5196 GenerateHashAddCharacter(masm, hash, c2, scratch); 5198 GenerateHashAddCharacter(masm, hash, c2, scratch);
5197 GenerateHashGetHash(masm, hash, scratch); 5199 GenerateHashGetHash(masm, hash, scratch);
5198 5200
5199 // Collect the two characters in a register. 5201 // Collect the two characters in a register.
5200 Register chars = c1; 5202 Register chars = c1;
5201 __ shl(c2, Immediate(kBitsPerByte)); 5203 __ shl(c2, Immediate(kBitsPerByte));
5202 __ orl(chars, c2); 5204 __ orl(chars, c2);
5203 5205
5204 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5206 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5205 // hash: hash of two character string. 5207 // hash: hash of two character string.
5206 5208
5207 // Load the symbol table. 5209 // Load the string table.
5208 Register symbol_table = c2; 5210 Register string_table = c2;
5209 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); 5211 __ LoadRoot(string_table, Heap::kStringTableRootIndex);
5210 5212
5211 // Calculate capacity mask from the symbol table capacity. 5213 // Calculate capacity mask from the string table capacity.
5212 Register mask = scratch2; 5214 Register mask = scratch2;
5213 __ SmiToInteger32(mask, 5215 __ SmiToInteger32(mask,
5214 FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); 5216 FieldOperand(string_table, StringTable::kCapacityOffset));
5215 __ decl(mask); 5217 __ decl(mask);
5216 5218
5217 Register map = scratch4; 5219 Register map = scratch4;
5218 5220
5219 // Registers 5221 // Registers
5220 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 5222 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
5221 // hash: hash of two character string (32-bit int) 5223 // hash: hash of two character string (32-bit int)
5222 // symbol_table: symbol table 5224 // string_table: string table
5223 // mask: capacity mask (32-bit int) 5225 // mask: capacity mask (32-bit int)
5224 // map: - 5226 // map: -
5225 // scratch: - 5227 // scratch: -
5226 5228
5227 // Perform a number of probes in the symbol table. 5229 // Perform a number of probes in the string table.
5228 static const int kProbes = 4; 5230 static const int kProbes = 4;
5229 Label found_in_symbol_table; 5231 Label found_in_string_table;
5230 Label next_probe[kProbes]; 5232 Label next_probe[kProbes];
5231 Register candidate = scratch; // Scratch register contains candidate. 5233 Register candidate = scratch; // Scratch register contains candidate.
5232 for (int i = 0; i < kProbes; i++) { 5234 for (int i = 0; i < kProbes; i++) {
5233 // Calculate entry in symbol table. 5235 // Calculate entry in string table.
5234 __ movl(scratch, hash); 5236 __ movl(scratch, hash);
5235 if (i > 0) { 5237 if (i > 0) {
5236 __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i))); 5238 __ addl(scratch, Immediate(StringTable::GetProbeOffset(i)));
5237 } 5239 }
5238 __ andl(scratch, mask); 5240 __ andl(scratch, mask);
5239 5241
5240 // Load the entry from the symbol table. 5242 // Load the entry from the string table.
5241 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 5243 STATIC_ASSERT(StringTable::kEntrySize == 1);
5242 __ movq(candidate, 5244 __ movq(candidate,
5243 FieldOperand(symbol_table, 5245 FieldOperand(string_table,
5244 scratch, 5246 scratch,
5245 times_pointer_size, 5247 times_pointer_size,
5246 SymbolTable::kElementsStartOffset)); 5248 StringTable::kElementsStartOffset));
5247 5249
5248 // If entry is undefined no string with this hash can be found. 5250 // If entry is undefined no string with this hash can be found.
5249 Label is_string; 5251 Label is_string;
5250 __ CmpObjectType(candidate, ODDBALL_TYPE, map); 5252 __ CmpObjectType(candidate, ODDBALL_TYPE, map);
5251 __ j(not_equal, &is_string, Label::kNear); 5253 __ j(not_equal, &is_string, Label::kNear);
5252 5254
5253 __ CompareRoot(candidate, Heap::kUndefinedValueRootIndex); 5255 __ CompareRoot(candidate, Heap::kUndefinedValueRootIndex);
5254 __ j(equal, not_found); 5256 __ j(equal, not_found);
5255 // Must be the hole (deleted entry). 5257 // Must be the hole (deleted entry).
5256 if (FLAG_debug_code) { 5258 if (FLAG_debug_code) {
5257 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 5259 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
5258 __ cmpq(kScratchRegister, candidate); 5260 __ cmpq(kScratchRegister, candidate);
5259 __ Assert(equal, "oddball in symbol table is not undefined or the hole"); 5261 __ Assert(equal, "oddball in string table is not undefined or the hole");
5260 } 5262 }
5261 __ jmp(&next_probe[i]); 5263 __ jmp(&next_probe[i]);
5262 5264
5263 __ bind(&is_string); 5265 __ bind(&is_string);
5264 5266
5265 // If length is not 2 the string is not a candidate. 5267 // If length is not 2 the string is not a candidate.
5266 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset), 5268 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset),
5267 Smi::FromInt(2)); 5269 Smi::FromInt(2));
5268 __ j(not_equal, &next_probe[i]); 5270 __ j(not_equal, &next_probe[i]);
5269 5271
5270 // We use kScratchRegister as a temporary register in assumption that 5272 // We use kScratchRegister as a temporary register in assumption that
5271 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly 5273 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly
5272 Register temp = kScratchRegister; 5274 Register temp = kScratchRegister;
5273 5275
5274 // Check that the candidate is a non-external ASCII string. 5276 // Check that the candidate is a non-external ASCII string.
5275 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset)); 5277 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset));
5276 __ JumpIfInstanceTypeIsNotSequentialAscii( 5278 __ JumpIfInstanceTypeIsNotSequentialAscii(
5277 temp, temp, &next_probe[i]); 5279 temp, temp, &next_probe[i]);
5278 5280
5279 // Check if the two characters match. 5281 // Check if the two characters match.
5280 __ movl(temp, FieldOperand(candidate, SeqOneByteString::kHeaderSize)); 5282 __ movl(temp, FieldOperand(candidate, SeqOneByteString::kHeaderSize));
5281 __ andl(temp, Immediate(0x0000ffff)); 5283 __ andl(temp, Immediate(0x0000ffff));
5282 __ cmpl(chars, temp); 5284 __ cmpl(chars, temp);
5283 __ j(equal, &found_in_symbol_table); 5285 __ j(equal, &found_in_string_table);
5284 __ bind(&next_probe[i]); 5286 __ bind(&next_probe[i]);
5285 } 5287 }
5286 5288
5287 // No matching 2 character string found by probing. 5289 // No matching 2 character string found by probing.
5288 __ jmp(not_found); 5290 __ jmp(not_found);
5289 5291
5290 // Scratch register contains result when we fall through to here. 5292 // Scratch register contains result when we fall through to here.
5291 Register result = candidate; 5293 Register result = candidate;
5292 __ bind(&found_in_symbol_table); 5294 __ bind(&found_in_string_table);
5293 if (!result.is(rax)) { 5295 if (!result.is(rax)) {
5294 __ movq(rax, result); 5296 __ movq(rax, result);
5295 } 5297 }
5296 } 5298 }
5297 5299
5298 5300
5299 void StringHelper::GenerateHashInit(MacroAssembler* masm, 5301 void StringHelper::GenerateHashInit(MacroAssembler* masm,
5300 Register hash, 5302 Register hash,
5301 Register character, 5303 Register character,
5302 Register scratch) { 5304 Register scratch) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
5408 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag)); 5410 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
5409 STATIC_ASSERT(kIsIndirectStringMask != 0); 5411 STATIC_ASSERT(kIsIndirectStringMask != 0);
5410 __ testb(rbx, Immediate(kIsIndirectStringMask)); 5412 __ testb(rbx, Immediate(kIsIndirectStringMask));
5411 __ j(zero, &seq_or_external_string, Label::kNear); 5413 __ j(zero, &seq_or_external_string, Label::kNear);
5412 5414
5413 __ testb(rbx, Immediate(kSlicedNotConsMask)); 5415 __ testb(rbx, Immediate(kSlicedNotConsMask));
5414 __ j(not_zero, &sliced_string, Label::kNear); 5416 __ j(not_zero, &sliced_string, Label::kNear);
5415 // Cons string. Check whether it is flat, then fetch first part. 5417 // Cons string. Check whether it is flat, then fetch first part.
5416 // Flat cons strings have an empty second part. 5418 // Flat cons strings have an empty second part.
5417 __ CompareRoot(FieldOperand(rax, ConsString::kSecondOffset), 5419 __ CompareRoot(FieldOperand(rax, ConsString::kSecondOffset),
5418 Heap::kEmptyStringRootIndex); 5420 Heap::kempty_stringRootIndex);
5419 __ j(not_equal, &runtime); 5421 __ j(not_equal, &runtime);
5420 __ movq(rdi, FieldOperand(rax, ConsString::kFirstOffset)); 5422 __ movq(rdi, FieldOperand(rax, ConsString::kFirstOffset));
5421 // Update instance type. 5423 // Update instance type.
5422 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 5424 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
5423 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 5425 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
5424 __ jmp(&underlying_unpacked, Label::kNear); 5426 __ jmp(&underlying_unpacked, Label::kNear);
5425 5427
5426 __ bind(&sliced_string); 5428 __ bind(&sliced_string);
5427 // Sliced string. Fetch parent and correct start index by offset. 5429 // Sliced string. Fetch parent and correct start index by offset.
5428 __ addq(rdx, FieldOperand(rax, SlicedString::kOffsetOffset)); 5430 __ addq(rdx, FieldOperand(rax, SlicedString::kOffsetOffset));
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
5844 if (Token::IsOrderedRelationalCompareOp(op_)) { 5846 if (Token::IsOrderedRelationalCompareOp(op_)) {
5845 __ Cmp(rdx, masm->isolate()->factory()->undefined_value()); 5847 __ Cmp(rdx, masm->isolate()->factory()->undefined_value());
5846 __ j(equal, &unordered); 5848 __ j(equal, &unordered);
5847 } 5849 }
5848 5850
5849 __ bind(&miss); 5851 __ bind(&miss);
5850 GenerateMiss(masm); 5852 GenerateMiss(masm);
5851 } 5853 }
5852 5854
5853 5855
5854 void ICCompareStub::GenerateSymbols(MacroAssembler* masm) { 5856 void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) {
5855 ASSERT(state_ == CompareIC::SYMBOL); 5857 ASSERT(state_ == CompareIC::INTERNALIZED_STRING);
5856 ASSERT(GetCondition() == equal); 5858 ASSERT(GetCondition() == equal);
5857 5859
5858 // Registers containing left and right operands respectively. 5860 // Registers containing left and right operands respectively.
5859 Register left = rdx; 5861 Register left = rdx;
5860 Register right = rax; 5862 Register right = rax;
5861 Register tmp1 = rcx; 5863 Register tmp1 = rcx;
5862 Register tmp2 = rbx; 5864 Register tmp2 = rbx;
5863 5865
5864 // Check that both operands are heap objects. 5866 // Check that both operands are heap objects.
5865 Label miss; 5867 Label miss;
5866 Condition cond = masm->CheckEitherSmi(left, right, tmp1); 5868 Condition cond = masm->CheckEitherSmi(left, right, tmp1);
5867 __ j(cond, &miss, Label::kNear); 5869 __ j(cond, &miss, Label::kNear);
5868 5870
5869 // Check that both operands are symbols. 5871 // Check that both operands are internalized strings.
5870 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset)); 5872 __ movq(tmp1, FieldOperand(left, HeapObject::kMapOffset));
5871 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset)); 5873 __ movq(tmp2, FieldOperand(right, HeapObject::kMapOffset));
5872 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset)); 5874 __ movzxbq(tmp1, FieldOperand(tmp1, Map::kInstanceTypeOffset));
5873 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset)); 5875 __ movzxbq(tmp2, FieldOperand(tmp2, Map::kInstanceTypeOffset));
5874 STATIC_ASSERT(kSymbolTag != 0); 5876 STATIC_ASSERT(kInternalizedTag != 0);
5875 __ and_(tmp1, tmp2); 5877 __ and_(tmp1, tmp2);
5876 __ testb(tmp1, Immediate(kIsSymbolMask)); 5878 __ testb(tmp1, Immediate(kIsInternalizedMask));
5877 __ j(zero, &miss, Label::kNear); 5879 __ j(zero, &miss, Label::kNear);
5878 5880
5879 // Symbols are compared by identity. 5881 // Internalized strings are compared by identity.
5880 Label done; 5882 Label done;
5881 __ cmpq(left, right); 5883 __ cmpq(left, right);
5882 // Make sure rax is non-zero. At this point input operands are 5884 // Make sure rax is non-zero. At this point input operands are
5883 // guaranteed to be non-zero. 5885 // guaranteed to be non-zero.
5884 ASSERT(right.is(rax)); 5886 ASSERT(right.is(rax));
5885 __ j(not_equal, &done, Label::kNear); 5887 __ j(not_equal, &done, Label::kNear);
5886 STATIC_ASSERT(EQUAL == 0); 5888 STATIC_ASSERT(EQUAL == 0);
5887 STATIC_ASSERT(kSmiTag == 0); 5889 STATIC_ASSERT(kSmiTag == 0);
5888 __ Move(rax, Smi::FromInt(EQUAL)); 5890 __ Move(rax, Smi::FromInt(EQUAL));
5889 __ bind(&done); 5891 __ bind(&done);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5928 __ cmpq(left, right); 5930 __ cmpq(left, right);
5929 __ j(not_equal, &not_same, Label::kNear); 5931 __ j(not_equal, &not_same, Label::kNear);
5930 STATIC_ASSERT(EQUAL == 0); 5932 STATIC_ASSERT(EQUAL == 0);
5931 STATIC_ASSERT(kSmiTag == 0); 5933 STATIC_ASSERT(kSmiTag == 0);
5932 __ Move(rax, Smi::FromInt(EQUAL)); 5934 __ Move(rax, Smi::FromInt(EQUAL));
5933 __ ret(0); 5935 __ ret(0);
5934 5936
5935 // Handle not identical strings. 5937 // Handle not identical strings.
5936 __ bind(&not_same); 5938 __ bind(&not_same);
5937 5939
5938 // Check that both strings are symbols. If they are, we're done 5940 // Check that both strings are internalized strings. If they are, we're done
5939 // because we already know they are not identical. 5941 // because we already know they are not identical.
5940 if (equality) { 5942 if (equality) {
5941 Label do_compare; 5943 Label do_compare;
5942 STATIC_ASSERT(kSymbolTag != 0); 5944 STATIC_ASSERT(kInternalizedTag != 0);
5943 __ and_(tmp1, tmp2); 5945 __ and_(tmp1, tmp2);
5944 __ testb(tmp1, Immediate(kIsSymbolMask)); 5946 __ testb(tmp1, Immediate(kIsInternalizedMask));
5945 __ j(zero, &do_compare, Label::kNear); 5947 __ j(zero, &do_compare, Label::kNear);
5946 // Make sure rax is non-zero. At this point input operands are 5948 // Make sure rax is non-zero. At this point input operands are
5947 // guaranteed to be non-zero. 5949 // guaranteed to be non-zero.
5948 ASSERT(right.is(rax)); 5950 ASSERT(right.is(rax));
5949 __ ret(0); 5951 __ ret(0);
5950 __ bind(&do_compare); 5952 __ bind(&do_compare);
5951 } 5953 }
5952 5954
5953 // Check that both strings are sequential ASCII. 5955 // Check that both strings are sequential ASCII.
5954 Label runtime; 5956 Label runtime;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
6082 6084
6083 // Stop if found the property. 6085 // Stop if found the property.
6084 __ Cmp(entity_name, Handle<String>(name)); 6086 __ Cmp(entity_name, Handle<String>(name));
6085 __ j(equal, miss); 6087 __ j(equal, miss);
6086 6088
6087 Label the_hole; 6089 Label the_hole;
6088 // Check for the hole and skip. 6090 // Check for the hole and skip.
6089 __ CompareRoot(entity_name, Heap::kTheHoleValueRootIndex); 6091 __ CompareRoot(entity_name, Heap::kTheHoleValueRootIndex);
6090 __ j(equal, &the_hole, Label::kNear); 6092 __ j(equal, &the_hole, Label::kNear);
6091 6093
6092 // Check if the entry name is not a symbol. 6094 // Check if the entry name is not an internalized string.
6093 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset)); 6095 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
6094 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset), 6096 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset),
6095 Immediate(kIsSymbolMask)); 6097 Immediate(kIsInternalizedMask));
6096 __ j(zero, miss); 6098 __ j(zero, miss);
6097 6099
6098 __ bind(&the_hole); 6100 __ bind(&the_hole);
6099 } 6101 }
6100 6102
6101 StringDictionaryLookupStub stub(properties, 6103 StringDictionaryLookupStub stub(properties,
6102 r0, 6104 r0,
6103 r0, 6105 r0,
6104 StringDictionaryLookupStub::NEGATIVE_LOOKUP); 6106 StringDictionaryLookupStub::NEGATIVE_LOOKUP);
6105 __ Push(Handle<Object>(name)); 6107 __ Push(Handle<Object>(name));
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
6214 kElementsStartOffset - kHeapObjectTag)); 6216 kElementsStartOffset - kHeapObjectTag));
6215 6217
6216 __ Cmp(scratch, masm->isolate()->factory()->undefined_value()); 6218 __ Cmp(scratch, masm->isolate()->factory()->undefined_value());
6217 __ j(equal, &not_in_dictionary); 6219 __ j(equal, &not_in_dictionary);
6218 6220
6219 // Stop if found the property. 6221 // Stop if found the property.
6220 __ cmpq(scratch, Operand(rsp, 3 * kPointerSize)); 6222 __ cmpq(scratch, Operand(rsp, 3 * kPointerSize));
6221 __ j(equal, &in_dictionary); 6223 __ j(equal, &in_dictionary);
6222 6224
6223 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) { 6225 if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
6224 // If we hit a non symbol key during negative lookup 6226 // If we hit a non internalized string key during negative lookup
6225 // we have to bailout as this key might be equal to the 6227 // we have to bailout as this key might be equal to the
6226 // key we are looking for. 6228 // key we are looking for.
6227 6229
6228 // Check if the entry name is not a symbol. 6230 // Check if the entry name is not an internalized string.
6229 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset)); 6231 __ movq(scratch, FieldOperand(scratch, HeapObject::kMapOffset));
6230 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset), 6232 __ testb(FieldOperand(scratch, Map::kInstanceTypeOffset),
6231 Immediate(kIsSymbolMask)); 6233 Immediate(kIsInternalizedMask));
6232 __ j(zero, &maybe_in_dictionary); 6234 __ j(zero, &maybe_in_dictionary);
6233 } 6235 }
6234 } 6236 }
6235 6237
6236 __ bind(&maybe_in_dictionary); 6238 __ bind(&maybe_in_dictionary);
6237 // If we are doing negative lookup then probing failure should be 6239 // If we are doing negative lookup then probing failure should be
6238 // treated as a lookup success. For positive lookup probing failure 6240 // treated as a lookup success. For positive lookup probing failure
6239 // should be treated as lookup failure. 6241 // should be treated as lookup failure.
6240 if (mode_ == POSITIVE_LOOKUP) { 6242 if (mode_ == POSITIVE_LOOKUP) {
6241 __ movq(scratch, Immediate(0)); 6243 __ movq(scratch, Immediate(0));
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
6712 #endif 6714 #endif
6713 6715
6714 __ Ret(); 6716 __ Ret();
6715 } 6717 }
6716 6718
6717 #undef __ 6719 #undef __
6718 6720
6719 } } // namespace v8::internal 6721 } } // namespace v8::internal
6720 6722
6721 #endif // V8_TARGET_ARCH_X64 6723 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698