OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 } | 357 } |
358 } else { | 358 } else { |
359 // Order of moves is not important. | 359 // Order of moves is not important. |
360 __ mov(left_arg, left); | 360 __ mov(left_arg, left); |
361 __ mov(right_arg, right); | 361 __ mov(right_arg, right); |
362 } | 362 } |
363 } | 363 } |
364 | 364 |
365 // Update flags to indicate that arguments are in registers. | 365 // Update flags to indicate that arguments are in registers. |
366 SetArgsInRegisters(); | 366 SetArgsInRegisters(); |
367 __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1); | 367 __ IncrementCounter( |
| 368 masm->isolate()->counters()->generic_binary_stub_calls_regs(), 1); |
368 } | 369 } |
369 | 370 |
370 // Call the stub. | 371 // Call the stub. |
371 __ CallStub(this); | 372 __ CallStub(this); |
372 } | 373 } |
373 | 374 |
374 | 375 |
375 void GenericBinaryOpStub::GenerateCall( | 376 void GenericBinaryOpStub::GenerateCall( |
376 MacroAssembler* masm, | 377 MacroAssembler* masm, |
377 Register left, | 378 Register left, |
(...skipping 15 matching lines...) Expand all Loading... |
393 // For non-commutative operations, left and right_arg might be | 394 // For non-commutative operations, left and right_arg might be |
394 // the same register. Therefore, the order of the moves is | 395 // the same register. Therefore, the order of the moves is |
395 // important here in order to not overwrite left before moving | 396 // important here in order to not overwrite left before moving |
396 // it to left_arg. | 397 // it to left_arg. |
397 __ mov(left_arg, left); | 398 __ mov(left_arg, left); |
398 __ mov(right_arg, Immediate(right)); | 399 __ mov(right_arg, Immediate(right)); |
399 } | 400 } |
400 | 401 |
401 // Update flags to indicate that arguments are in registers. | 402 // Update flags to indicate that arguments are in registers. |
402 SetArgsInRegisters(); | 403 SetArgsInRegisters(); |
403 __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1); | 404 __ IncrementCounter( |
| 405 masm->isolate()->counters()->generic_binary_stub_calls_regs(), 1); |
404 } | 406 } |
405 | 407 |
406 // Call the stub. | 408 // Call the stub. |
407 __ CallStub(this); | 409 __ CallStub(this); |
408 } | 410 } |
409 | 411 |
410 | 412 |
411 void GenericBinaryOpStub::GenerateCall( | 413 void GenericBinaryOpStub::GenerateCall( |
412 MacroAssembler* masm, | 414 MacroAssembler* masm, |
413 Smi* left, | 415 Smi* left, |
(...skipping 14 matching lines...) Expand all Loading... |
428 } else { | 430 } else { |
429 // For non-commutative operations, right and left_arg might be | 431 // For non-commutative operations, right and left_arg might be |
430 // the same register. Therefore, the order of the moves is | 432 // the same register. Therefore, the order of the moves is |
431 // important here in order to not overwrite right before moving | 433 // important here in order to not overwrite right before moving |
432 // it to right_arg. | 434 // it to right_arg. |
433 __ mov(right_arg, right); | 435 __ mov(right_arg, right); |
434 __ mov(left_arg, Immediate(left)); | 436 __ mov(left_arg, Immediate(left)); |
435 } | 437 } |
436 // Update flags to indicate that arguments are in registers. | 438 // Update flags to indicate that arguments are in registers. |
437 SetArgsInRegisters(); | 439 SetArgsInRegisters(); |
438 __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1); | 440 Counters* counters = masm->isolate()->counters(); |
| 441 __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1); |
439 } | 442 } |
440 | 443 |
441 // Call the stub. | 444 // Call the stub. |
442 __ CallStub(this); | 445 __ CallStub(this); |
443 } | 446 } |
444 | 447 |
445 | 448 |
446 class FloatingPointHelper : public AllStatic { | 449 class FloatingPointHelper : public AllStatic { |
447 public: | 450 public: |
448 | 451 |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 | 874 |
872 default: | 875 default: |
873 break; | 876 break; |
874 } | 877 } |
875 } | 878 } |
876 | 879 |
877 | 880 |
878 void GenericBinaryOpStub::Generate(MacroAssembler* masm) { | 881 void GenericBinaryOpStub::Generate(MacroAssembler* masm) { |
879 Label call_runtime; | 882 Label call_runtime; |
880 | 883 |
881 __ IncrementCounter(COUNTERS->generic_binary_stub_calls(), 1); | 884 Counters* counters = masm->isolate()->counters(); |
| 885 __ IncrementCounter(counters->generic_binary_stub_calls(), 1); |
882 | 886 |
883 if (runtime_operands_type_ == BinaryOpIC::UNINIT_OR_SMI) { | 887 if (runtime_operands_type_ == BinaryOpIC::UNINIT_OR_SMI) { |
884 Label slow; | 888 Label slow; |
885 if (ShouldGenerateSmiCode()) GenerateSmiCode(masm, &slow); | 889 if (ShouldGenerateSmiCode()) GenerateSmiCode(masm, &slow); |
886 __ bind(&slow); | 890 __ bind(&slow); |
887 GenerateTypeTransition(masm); | 891 GenerateTypeTransition(masm); |
888 } | 892 } |
889 | 893 |
890 // Generate fast case smi code if requested. This flag is set when the fast | 894 // Generate fast case smi code if requested. This flag is set when the fast |
891 // case smi code is not generated by the caller. Generating it here will speed | 895 // case smi code is not generated by the caller. Generating it here will speed |
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2193 break; | 2197 break; |
2194 default: | 2198 default: |
2195 UNREACHABLE(); | 2199 UNREACHABLE(); |
2196 } | 2200 } |
2197 } | 2201 } |
2198 | 2202 |
2199 | 2203 |
2200 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { | 2204 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { |
2201 Label call_runtime; | 2205 Label call_runtime; |
2202 | 2206 |
2203 __ IncrementCounter(COUNTERS->generic_binary_stub_calls(), 1); | 2207 Counters* counters = masm->isolate()->counters(); |
| 2208 __ IncrementCounter(counters->generic_binary_stub_calls(), 1); |
2204 | 2209 |
2205 switch (op_) { | 2210 switch (op_) { |
2206 case Token::ADD: | 2211 case Token::ADD: |
2207 case Token::SUB: | 2212 case Token::SUB: |
2208 case Token::MUL: | 2213 case Token::MUL: |
2209 case Token::DIV: | 2214 case Token::DIV: |
2210 break; | 2215 break; |
2211 case Token::MOD: | 2216 case Token::MOD: |
2212 case Token::BIT_OR: | 2217 case Token::BIT_OR: |
2213 case Token::BIT_AND: | 2218 case Token::BIT_AND: |
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3899 // Load used arguments before starting to push arguments for call to native | 3904 // Load used arguments before starting to push arguments for call to native |
3900 // RegExp code to avoid handling changing stack height. | 3905 // RegExp code to avoid handling changing stack height. |
3901 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); | 3906 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); |
3902 __ SmiUntag(ebx); // Previous index from smi. | 3907 __ SmiUntag(ebx); // Previous index from smi. |
3903 | 3908 |
3904 // eax: subject string | 3909 // eax: subject string |
3905 // ebx: previous index | 3910 // ebx: previous index |
3906 // edx: code | 3911 // edx: code |
3907 // edi: encoding of subject string (1 if ascii 0 if two_byte); | 3912 // edi: encoding of subject string (1 if ascii 0 if two_byte); |
3908 // All checks done. Now push arguments for native regexp code. | 3913 // All checks done. Now push arguments for native regexp code. |
3909 __ IncrementCounter(COUNTERS->regexp_entry_native(), 1); | 3914 Counters* counters = masm->isolate()->counters(); |
| 3915 __ IncrementCounter(counters->regexp_entry_native(), 1); |
3910 | 3916 |
3911 // Isolates: note we add an additional parameter here (isolate pointer). | 3917 // Isolates: note we add an additional parameter here (isolate pointer). |
3912 static const int kRegExpExecuteArguments = 8; | 3918 static const int kRegExpExecuteArguments = 8; |
3913 __ EnterApiExitFrame(kRegExpExecuteArguments); | 3919 __ EnterApiExitFrame(kRegExpExecuteArguments); |
3914 | 3920 |
3915 // Argument 8: Pass current isolate address. | 3921 // Argument 8: Pass current isolate address. |
3916 __ mov(Operand(esp, 7 * kPointerSize), | 3922 __ mov(Operand(esp, 7 * kPointerSize), |
3917 Immediate(ExternalReference::isolate_address())); | 3923 Immediate(ExternalReference::isolate_address())); |
3918 | 3924 |
3919 // Argument 7: Indicate that this is a direct call from JavaScript. | 3925 // Argument 7: Indicate that this is a direct call from JavaScript. |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4244 FixedArray::kHeaderSize)); | 4250 FixedArray::kHeaderSize)); |
4245 __ j(not_equal, not_found); | 4251 __ j(not_equal, not_found); |
4246 | 4252 |
4247 // Get the result from the cache. | 4253 // Get the result from the cache. |
4248 __ bind(&load_result_from_cache); | 4254 __ bind(&load_result_from_cache); |
4249 __ mov(result, | 4255 __ mov(result, |
4250 FieldOperand(number_string_cache, | 4256 FieldOperand(number_string_cache, |
4251 index, | 4257 index, |
4252 times_twice_pointer_size, | 4258 times_twice_pointer_size, |
4253 FixedArray::kHeaderSize + kPointerSize)); | 4259 FixedArray::kHeaderSize + kPointerSize)); |
4254 __ IncrementCounter(COUNTERS->number_to_string_native(), 1); | 4260 Counters* counters = masm->isolate()->counters(); |
| 4261 __ IncrementCounter(counters->number_to_string_native(), 1); |
4255 } | 4262 } |
4256 | 4263 |
4257 | 4264 |
4258 void NumberToStringStub::Generate(MacroAssembler* masm) { | 4265 void NumberToStringStub::Generate(MacroAssembler* masm) { |
4259 Label runtime; | 4266 Label runtime; |
4260 | 4267 |
4261 __ mov(ebx, Operand(esp, kPointerSize)); | 4268 __ mov(ebx, Operand(esp, kPointerSize)); |
4262 | 4269 |
4263 // Generate code to lookup number in the number string cache. | 4270 // Generate code to lookup number in the number string cache. |
4264 GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, false, &runtime); | 4271 GenerateLookupNumberStringCache(masm, ebx, eax, ecx, edx, false, &runtime); |
(...skipping 1262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5527 // Both arguments are strings. | 5534 // Both arguments are strings. |
5528 // eax: first string | 5535 // eax: first string |
5529 // edx: second string | 5536 // edx: second string |
5530 // Check if either of the strings are empty. In that case return the other. | 5537 // Check if either of the strings are empty. In that case return the other. |
5531 NearLabel second_not_zero_length, both_not_zero_length; | 5538 NearLabel second_not_zero_length, both_not_zero_length; |
5532 __ mov(ecx, FieldOperand(edx, String::kLengthOffset)); | 5539 __ mov(ecx, FieldOperand(edx, String::kLengthOffset)); |
5533 STATIC_ASSERT(kSmiTag == 0); | 5540 STATIC_ASSERT(kSmiTag == 0); |
5534 __ test(ecx, Operand(ecx)); | 5541 __ test(ecx, Operand(ecx)); |
5535 __ j(not_zero, &second_not_zero_length); | 5542 __ j(not_zero, &second_not_zero_length); |
5536 // Second string is empty, result is first string which is already in eax. | 5543 // Second string is empty, result is first string which is already in eax. |
5537 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 5544 Counters* counters = masm->isolate()->counters(); |
| 5545 __ IncrementCounter(counters->string_add_native(), 1); |
5538 __ ret(2 * kPointerSize); | 5546 __ ret(2 * kPointerSize); |
5539 __ bind(&second_not_zero_length); | 5547 __ bind(&second_not_zero_length); |
5540 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); | 5548 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); |
5541 STATIC_ASSERT(kSmiTag == 0); | 5549 STATIC_ASSERT(kSmiTag == 0); |
5542 __ test(ebx, Operand(ebx)); | 5550 __ test(ebx, Operand(ebx)); |
5543 __ j(not_zero, &both_not_zero_length); | 5551 __ j(not_zero, &both_not_zero_length); |
5544 // First string is empty, result is second string which is in edx. | 5552 // First string is empty, result is second string which is in edx. |
5545 __ mov(eax, edx); | 5553 __ mov(eax, edx); |
5546 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 5554 __ IncrementCounter(counters->string_add_native(), 1); |
5547 __ ret(2 * kPointerSize); | 5555 __ ret(2 * kPointerSize); |
5548 | 5556 |
5549 // Both strings are non-empty. | 5557 // Both strings are non-empty. |
5550 // eax: first string | 5558 // eax: first string |
5551 // ebx: length of first string as a smi | 5559 // ebx: length of first string as a smi |
5552 // ecx: length of second string as a smi | 5560 // ecx: length of second string as a smi |
5553 // edx: second string | 5561 // edx: second string |
5554 // Look at the length of the result of adding the two strings. | 5562 // Look at the length of the result of adding the two strings. |
5555 Label string_add_flat_result, longer_than_two; | 5563 Label string_add_flat_result, longer_than_two; |
5556 __ bind(&both_not_zero_length); | 5564 __ bind(&both_not_zero_length); |
(...skipping 13 matching lines...) Expand all Loading... |
5570 // Get the two characters forming the new string. | 5578 // Get the two characters forming the new string. |
5571 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); | 5579 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); |
5572 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); | 5580 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); |
5573 | 5581 |
5574 // Try to lookup two character string in symbol table. If it is not found | 5582 // Try to lookup two character string in symbol table. If it is not found |
5575 // just allocate a new one. | 5583 // just allocate a new one. |
5576 Label make_two_character_string, make_two_character_string_no_reload; | 5584 Label make_two_character_string, make_two_character_string_no_reload; |
5577 StringHelper::GenerateTwoCharacterSymbolTableProbe( | 5585 StringHelper::GenerateTwoCharacterSymbolTableProbe( |
5578 masm, ebx, ecx, eax, edx, edi, | 5586 masm, ebx, ecx, eax, edx, edi, |
5579 &make_two_character_string_no_reload, &make_two_character_string); | 5587 &make_two_character_string_no_reload, &make_two_character_string); |
5580 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 5588 __ IncrementCounter(counters->string_add_native(), 1); |
5581 __ ret(2 * kPointerSize); | 5589 __ ret(2 * kPointerSize); |
5582 | 5590 |
5583 // Allocate a two character string. | 5591 // Allocate a two character string. |
5584 __ bind(&make_two_character_string); | 5592 __ bind(&make_two_character_string); |
5585 // Reload the arguments. | 5593 // Reload the arguments. |
5586 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument. | 5594 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument. |
5587 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument. | 5595 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument. |
5588 // Get the two characters forming the new string. | 5596 // Get the two characters forming the new string. |
5589 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); | 5597 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); |
5590 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); | 5598 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); |
5591 __ bind(&make_two_character_string_no_reload); | 5599 __ bind(&make_two_character_string_no_reload); |
5592 __ IncrementCounter(COUNTERS->string_add_make_two_char(), 1); | 5600 __ IncrementCounter(counters->string_add_make_two_char(), 1); |
5593 __ AllocateAsciiString(eax, // Result. | 5601 __ AllocateAsciiString(eax, // Result. |
5594 2, // Length. | 5602 2, // Length. |
5595 edi, // Scratch 1. | 5603 edi, // Scratch 1. |
5596 edx, // Scratch 2. | 5604 edx, // Scratch 2. |
5597 &string_add_runtime); | 5605 &string_add_runtime); |
5598 // Pack both characters in ebx. | 5606 // Pack both characters in ebx. |
5599 __ shl(ecx, kBitsPerByte); | 5607 __ shl(ecx, kBitsPerByte); |
5600 __ or_(ebx, Operand(ecx)); | 5608 __ or_(ebx, Operand(ecx)); |
5601 // Set the characters in the new string. | 5609 // Set the characters in the new string. |
5602 __ mov_w(FieldOperand(eax, SeqAsciiString::kHeaderSize), ebx); | 5610 __ mov_w(FieldOperand(eax, SeqAsciiString::kHeaderSize), ebx); |
5603 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 5611 __ IncrementCounter(counters->string_add_native(), 1); |
5604 __ ret(2 * kPointerSize); | 5612 __ ret(2 * kPointerSize); |
5605 | 5613 |
5606 __ bind(&longer_than_two); | 5614 __ bind(&longer_than_two); |
5607 // Check if resulting string will be flat. | 5615 // Check if resulting string will be flat. |
5608 __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength))); | 5616 __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength))); |
5609 __ j(below, &string_add_flat_result); | 5617 __ j(below, &string_add_flat_result); |
5610 | 5618 |
5611 // If result is not supposed to be flat allocate a cons string object. If both | 5619 // If result is not supposed to be flat allocate a cons string object. If both |
5612 // strings are ascii the result is an ascii cons string. | 5620 // strings are ascii the result is an ascii cons string. |
5613 Label non_ascii, allocated, ascii_data; | 5621 Label non_ascii, allocated, ascii_data; |
(...skipping 10 matching lines...) Expand all Loading... |
5624 __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime); | 5632 __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime); |
5625 __ bind(&allocated); | 5633 __ bind(&allocated); |
5626 // Fill the fields of the cons string. | 5634 // Fill the fields of the cons string. |
5627 if (FLAG_debug_code) __ AbortIfNotSmi(ebx); | 5635 if (FLAG_debug_code) __ AbortIfNotSmi(ebx); |
5628 __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx); | 5636 __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx); |
5629 __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset), | 5637 __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset), |
5630 Immediate(String::kEmptyHashField)); | 5638 Immediate(String::kEmptyHashField)); |
5631 __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax); | 5639 __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax); |
5632 __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx); | 5640 __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx); |
5633 __ mov(eax, ecx); | 5641 __ mov(eax, ecx); |
5634 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 5642 __ IncrementCounter(counters->string_add_native(), 1); |
5635 __ ret(2 * kPointerSize); | 5643 __ ret(2 * kPointerSize); |
5636 __ bind(&non_ascii); | 5644 __ bind(&non_ascii); |
5637 // At least one of the strings is two-byte. Check whether it happens | 5645 // At least one of the strings is two-byte. Check whether it happens |
5638 // to contain only ascii characters. | 5646 // to contain only ascii characters. |
5639 // ecx: first instance type AND second instance type. | 5647 // ecx: first instance type AND second instance type. |
5640 // edi: second instance type. | 5648 // edi: second instance type. |
5641 __ test(ecx, Immediate(kAsciiDataHintMask)); | 5649 __ test(ecx, Immediate(kAsciiDataHintMask)); |
5642 __ j(not_zero, &ascii_data); | 5650 __ j(not_zero, &ascii_data); |
5643 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5651 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
5644 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5652 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5701 // Load second argument and locate first character. | 5709 // Load second argument and locate first character. |
5702 __ mov(edx, Operand(esp, 1 * kPointerSize)); | 5710 __ mov(edx, Operand(esp, 1 * kPointerSize)); |
5703 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); | 5711 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); |
5704 __ SmiUntag(edi); | 5712 __ SmiUntag(edi); |
5705 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 5713 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
5706 // eax: result string | 5714 // eax: result string |
5707 // ecx: next character of result | 5715 // ecx: next character of result |
5708 // edx: first char of second argument | 5716 // edx: first char of second argument |
5709 // edi: length of second argument | 5717 // edi: length of second argument |
5710 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true); | 5718 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true); |
5711 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 5719 __ IncrementCounter(counters->string_add_native(), 1); |
5712 __ ret(2 * kPointerSize); | 5720 __ ret(2 * kPointerSize); |
5713 | 5721 |
5714 // Handle creating a flat two byte result. | 5722 // Handle creating a flat two byte result. |
5715 // eax: first string - known to be two byte | 5723 // eax: first string - known to be two byte |
5716 // ebx: length of resulting flat string as a smi | 5724 // ebx: length of resulting flat string as a smi |
5717 // edx: second string | 5725 // edx: second string |
5718 __ bind(&non_ascii_string_add_flat_result); | 5726 __ bind(&non_ascii_string_add_flat_result); |
5719 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5727 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
5720 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); | 5728 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); |
5721 __ j(not_zero, &string_add_runtime); | 5729 __ j(not_zero, &string_add_runtime); |
(...skipping 20 matching lines...) Expand all Loading... |
5742 // Load second argument and locate first character. | 5750 // Load second argument and locate first character. |
5743 __ mov(edx, Operand(esp, 1 * kPointerSize)); | 5751 __ mov(edx, Operand(esp, 1 * kPointerSize)); |
5744 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); | 5752 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); |
5745 __ SmiUntag(edi); | 5753 __ SmiUntag(edi); |
5746 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 5754 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
5747 // eax: result string | 5755 // eax: result string |
5748 // ecx: next character of result | 5756 // ecx: next character of result |
5749 // edx: first char of second argument | 5757 // edx: first char of second argument |
5750 // edi: length of second argument | 5758 // edi: length of second argument |
5751 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false); | 5759 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, false); |
5752 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 5760 __ IncrementCounter(counters->string_add_native(), 1); |
5753 __ ret(2 * kPointerSize); | 5761 __ ret(2 * kPointerSize); |
5754 | 5762 |
5755 // Just jump to runtime to add the two strings. | 5763 // Just jump to runtime to add the two strings. |
5756 __ bind(&string_add_runtime); | 5764 __ bind(&string_add_runtime); |
5757 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 5765 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
5758 | 5766 |
5759 if (call_builtin.is_linked()) { | 5767 if (call_builtin.is_linked()) { |
5760 __ bind(&call_builtin); | 5768 __ bind(&call_builtin); |
5761 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); | 5769 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); |
5762 } | 5770 } |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6167 __ SmiUntag(ebx); | 6175 __ SmiUntag(ebx); |
6168 __ add(esi, Operand(ebx)); | 6176 __ add(esi, Operand(ebx)); |
6169 | 6177 |
6170 // eax: result string | 6178 // eax: result string |
6171 // ecx: result length | 6179 // ecx: result length |
6172 // edx: original value of esi | 6180 // edx: original value of esi |
6173 // edi: first character of result | 6181 // edi: first character of result |
6174 // esi: character of sub string start | 6182 // esi: character of sub string start |
6175 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true); | 6183 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, true); |
6176 __ mov(esi, edx); // Restore esi. | 6184 __ mov(esi, edx); // Restore esi. |
6177 __ IncrementCounter(COUNTERS->sub_string_native(), 1); | 6185 Counters* counters = masm->isolate()->counters(); |
| 6186 __ IncrementCounter(counters->sub_string_native(), 1); |
6178 __ ret(3 * kPointerSize); | 6187 __ ret(3 * kPointerSize); |
6179 | 6188 |
6180 __ bind(&non_ascii_flat); | 6189 __ bind(&non_ascii_flat); |
6181 // eax: string | 6190 // eax: string |
6182 // ebx: instance type & kStringRepresentationMask | kStringEncodingMask | 6191 // ebx: instance type & kStringRepresentationMask | kStringEncodingMask |
6183 // ecx: result string length | 6192 // ecx: result string length |
6184 // Check for flat two byte string | 6193 // Check for flat two byte string |
6185 __ cmp(ebx, kSeqStringTag | kTwoByteStringTag); | 6194 __ cmp(ebx, kSeqStringTag | kTwoByteStringTag); |
6186 __ j(not_equal, &runtime); | 6195 __ j(not_equal, &runtime); |
6187 | 6196 |
(...skipping 20 matching lines...) Expand all Loading... |
6208 | 6217 |
6209 // eax: result string | 6218 // eax: result string |
6210 // ecx: result length | 6219 // ecx: result length |
6211 // edx: original value of esi | 6220 // edx: original value of esi |
6212 // edi: first character of result | 6221 // edi: first character of result |
6213 // esi: character of sub string start | 6222 // esi: character of sub string start |
6214 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false); | 6223 StringHelper::GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false); |
6215 __ mov(esi, edx); // Restore esi. | 6224 __ mov(esi, edx); // Restore esi. |
6216 | 6225 |
6217 __ bind(&return_eax); | 6226 __ bind(&return_eax); |
6218 __ IncrementCounter(COUNTERS->sub_string_native(), 1); | 6227 __ IncrementCounter(counters->sub_string_native(), 1); |
6219 __ ret(3 * kPointerSize); | 6228 __ ret(3 * kPointerSize); |
6220 | 6229 |
6221 // Just jump to runtime to create the sub string. | 6230 // Just jump to runtime to create the sub string. |
6222 __ bind(&runtime); | 6231 __ bind(&runtime); |
6223 __ TailCallRuntime(Runtime::kSubString, 3, 1); | 6232 __ TailCallRuntime(Runtime::kSubString, 3, 1); |
6224 } | 6233 } |
6225 | 6234 |
6226 | 6235 |
6227 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 6236 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
6228 Register left, | 6237 Register left, |
6229 Register right, | 6238 Register right, |
6230 Register scratch1, | 6239 Register scratch1, |
6231 Register scratch2, | 6240 Register scratch2, |
6232 Register scratch3) { | 6241 Register scratch3) { |
6233 Label result_not_equal; | 6242 Label result_not_equal; |
6234 Label result_greater; | 6243 Label result_greater; |
6235 Label compare_lengths; | 6244 Label compare_lengths; |
6236 | 6245 |
6237 __ IncrementCounter(COUNTERS->string_compare_native(), 1); | 6246 Counters* counters = masm->isolate()->counters(); |
| 6247 __ IncrementCounter(counters->string_compare_native(), 1); |
6238 | 6248 |
6239 // Find minimum length. | 6249 // Find minimum length. |
6240 NearLabel left_shorter; | 6250 NearLabel left_shorter; |
6241 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); | 6251 __ mov(scratch1, FieldOperand(left, String::kLengthOffset)); |
6242 __ mov(scratch3, scratch1); | 6252 __ mov(scratch3, scratch1); |
6243 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); | 6253 __ sub(scratch3, FieldOperand(right, String::kLengthOffset)); |
6244 | 6254 |
6245 Register length_delta = scratch3; | 6255 Register length_delta = scratch3; |
6246 | 6256 |
6247 __ j(less_equal, &left_shorter); | 6257 __ j(less_equal, &left_shorter); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6318 | 6328 |
6319 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left | 6329 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left |
6320 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right | 6330 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right |
6321 | 6331 |
6322 NearLabel not_same; | 6332 NearLabel not_same; |
6323 __ cmp(edx, Operand(eax)); | 6333 __ cmp(edx, Operand(eax)); |
6324 __ j(not_equal, ¬_same); | 6334 __ j(not_equal, ¬_same); |
6325 STATIC_ASSERT(EQUAL == 0); | 6335 STATIC_ASSERT(EQUAL == 0); |
6326 STATIC_ASSERT(kSmiTag == 0); | 6336 STATIC_ASSERT(kSmiTag == 0); |
6327 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); | 6337 __ Set(eax, Immediate(Smi::FromInt(EQUAL))); |
6328 __ IncrementCounter(COUNTERS->string_compare_native(), 1); | 6338 __ IncrementCounter(masm->isolate()->counters()->string_compare_native(), 1); |
6329 __ ret(2 * kPointerSize); | 6339 __ ret(2 * kPointerSize); |
6330 | 6340 |
6331 __ bind(¬_same); | 6341 __ bind(¬_same); |
6332 | 6342 |
6333 // Check that both objects are sequential ascii strings. | 6343 // Check that both objects are sequential ascii strings. |
6334 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); | 6344 __ JumpIfNotBothSequentialAsciiStrings(edx, eax, ecx, ebx, &runtime); |
6335 | 6345 |
6336 // Compare flat ascii strings. | 6346 // Compare flat ascii strings. |
6337 // Drop arguments from the stack. | 6347 // Drop arguments from the stack. |
6338 __ pop(ecx); | 6348 __ pop(ecx); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6479 // Do a tail call to the rewritten stub. | 6489 // Do a tail call to the rewritten stub. |
6480 __ jmp(Operand(edi)); | 6490 __ jmp(Operand(edi)); |
6481 } | 6491 } |
6482 | 6492 |
6483 | 6493 |
6484 #undef __ | 6494 #undef __ |
6485 | 6495 |
6486 } } // namespace v8::internal | 6496 } } // namespace v8::internal |
6487 | 6497 |
6488 #endif // V8_TARGET_ARCH_IA32 | 6498 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |