| 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 } | 352 } |
| 353 } else { | 353 } else { |
| 354 // Order of moves is not important. | 354 // Order of moves is not important. |
| 355 __ movq(left_arg, left); | 355 __ movq(left_arg, left); |
| 356 __ movq(right_arg, right); | 356 __ movq(right_arg, right); |
| 357 } | 357 } |
| 358 } | 358 } |
| 359 | 359 |
| 360 // Update flags to indicate that arguments are in registers. | 360 // Update flags to indicate that arguments are in registers. |
| 361 SetArgsInRegisters(); | 361 SetArgsInRegisters(); |
| 362 __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1); | 362 Counters* counters = masm->isolate()->counters(); |
| 363 __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1); |
| 363 } | 364 } |
| 364 | 365 |
| 365 // Call the stub. | 366 // Call the stub. |
| 366 __ CallStub(this); | 367 __ CallStub(this); |
| 367 } | 368 } |
| 368 | 369 |
| 369 | 370 |
| 370 void GenericBinaryOpStub::GenerateCall( | 371 void GenericBinaryOpStub::GenerateCall( |
| 371 MacroAssembler* masm, | 372 MacroAssembler* masm, |
| 372 Register left, | 373 Register left, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 388 // For non-commutative operations, left and right_arg might be | 389 // For non-commutative operations, left and right_arg might be |
| 389 // the same register. Therefore, the order of the moves is | 390 // the same register. Therefore, the order of the moves is |
| 390 // important here in order to not overwrite left before moving | 391 // important here in order to not overwrite left before moving |
| 391 // it to left_arg. | 392 // it to left_arg. |
| 392 __ movq(left_arg, left); | 393 __ movq(left_arg, left); |
| 393 __ Move(right_arg, right); | 394 __ Move(right_arg, right); |
| 394 } | 395 } |
| 395 | 396 |
| 396 // Update flags to indicate that arguments are in registers. | 397 // Update flags to indicate that arguments are in registers. |
| 397 SetArgsInRegisters(); | 398 SetArgsInRegisters(); |
| 398 __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1); | 399 Counters* counters = masm->isolate()->counters(); |
| 400 __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1); |
| 399 } | 401 } |
| 400 | 402 |
| 401 // Call the stub. | 403 // Call the stub. |
| 402 __ CallStub(this); | 404 __ CallStub(this); |
| 403 } | 405 } |
| 404 | 406 |
| 405 | 407 |
| 406 void GenericBinaryOpStub::GenerateCall( | 408 void GenericBinaryOpStub::GenerateCall( |
| 407 MacroAssembler* masm, | 409 MacroAssembler* masm, |
| 408 Smi* left, | 410 Smi* left, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 423 } else { | 425 } else { |
| 424 // For non-commutative operations, right and left_arg might be | 426 // For non-commutative operations, right and left_arg might be |
| 425 // the same register. Therefore, the order of the moves is | 427 // the same register. Therefore, the order of the moves is |
| 426 // important here in order to not overwrite right before moving | 428 // important here in order to not overwrite right before moving |
| 427 // it to right_arg. | 429 // it to right_arg. |
| 428 __ movq(right_arg, right); | 430 __ movq(right_arg, right); |
| 429 __ Move(left_arg, left); | 431 __ Move(left_arg, left); |
| 430 } | 432 } |
| 431 // Update flags to indicate that arguments are in registers. | 433 // Update flags to indicate that arguments are in registers. |
| 432 SetArgsInRegisters(); | 434 SetArgsInRegisters(); |
| 433 __ IncrementCounter(COUNTERS->generic_binary_stub_calls_regs(), 1); | 435 Counters* counters = masm->isolate()->counters(); |
| 436 __ IncrementCounter(counters->generic_binary_stub_calls_regs(), 1); |
| 434 } | 437 } |
| 435 | 438 |
| 436 // Call the stub. | 439 // Call the stub. |
| 437 __ CallStub(this); | 440 __ CallStub(this); |
| 438 } | 441 } |
| 439 | 442 |
| 440 | 443 |
| 441 class FloatingPointHelper : public AllStatic { | 444 class FloatingPointHelper : public AllStatic { |
| 442 public: | 445 public: |
| 443 // Load the operands from rdx and rax into xmm0 and xmm1, as doubles. | 446 // Load the operands from rdx and rax into xmm0 and xmm1, as doubles. |
| (...skipping 2148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2592 // r11: code | 2595 // r11: code |
| 2593 // Load used arguments before starting to push arguments for call to native | 2596 // Load used arguments before starting to push arguments for call to native |
| 2594 // RegExp code to avoid handling changing stack height. | 2597 // RegExp code to avoid handling changing stack height. |
| 2595 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset)); | 2598 __ SmiToInteger64(rbx, Operand(rsp, kPreviousIndexOffset)); |
| 2596 | 2599 |
| 2597 // rdi: subject string | 2600 // rdi: subject string |
| 2598 // rbx: previous index | 2601 // rbx: previous index |
| 2599 // rcx: encoding of subject string (1 if ascii 0 if two_byte); | 2602 // rcx: encoding of subject string (1 if ascii 0 if two_byte); |
| 2600 // r11: code | 2603 // r11: code |
| 2601 // All checks done. Now push arguments for native regexp code. | 2604 // All checks done. Now push arguments for native regexp code. |
| 2602 __ IncrementCounter(COUNTERS->regexp_entry_native(), 1); | 2605 Counters* counters = masm->isolate()->counters(); |
| 2606 __ IncrementCounter(counters->regexp_entry_native(), 1); |
| 2603 | 2607 |
| 2604 // Isolates: note we add an additional parameter here (isolate pointer). | 2608 // Isolates: note we add an additional parameter here (isolate pointer). |
| 2605 static const int kRegExpExecuteArguments = 8; | 2609 static const int kRegExpExecuteArguments = 8; |
| 2606 int argument_slots_on_stack = | 2610 int argument_slots_on_stack = |
| 2607 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); | 2611 masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments); |
| 2608 __ EnterApiExitFrame(argument_slots_on_stack); | 2612 __ EnterApiExitFrame(argument_slots_on_stack); |
| 2609 | 2613 |
| 2610 // Argument 8: Pass current isolate address. | 2614 // Argument 8: Pass current isolate address. |
| 2611 // __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), | 2615 // __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kPointerSize), |
| 2612 // Immediate(ExternalReference::isolate_address())); | 2616 // Immediate(ExternalReference::isolate_address())); |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2944 FixedArray::kHeaderSize)); | 2948 FixedArray::kHeaderSize)); |
| 2945 __ j(not_equal, not_found); | 2949 __ j(not_equal, not_found); |
| 2946 | 2950 |
| 2947 // Get the result from the cache. | 2951 // Get the result from the cache. |
| 2948 __ bind(&load_result_from_cache); | 2952 __ bind(&load_result_from_cache); |
| 2949 __ movq(result, | 2953 __ movq(result, |
| 2950 FieldOperand(number_string_cache, | 2954 FieldOperand(number_string_cache, |
| 2951 index, | 2955 index, |
| 2952 times_1, | 2956 times_1, |
| 2953 FixedArray::kHeaderSize + kPointerSize)); | 2957 FixedArray::kHeaderSize + kPointerSize)); |
| 2954 __ IncrementCounter(COUNTERS->number_to_string_native(), 1); | 2958 Counters* counters = masm->isolate()->counters(); |
| 2959 __ IncrementCounter(counters->number_to_string_native(), 1); |
| 2955 } | 2960 } |
| 2956 | 2961 |
| 2957 | 2962 |
| 2958 void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm, | 2963 void NumberToStringStub::GenerateConvertHashCodeToIndex(MacroAssembler* masm, |
| 2959 Register hash, | 2964 Register hash, |
| 2960 Register mask) { | 2965 Register mask) { |
| 2961 __ and_(hash, mask); | 2966 __ and_(hash, mask); |
| 2962 // Each entry in string cache consists of two pointer sized fields, | 2967 // Each entry in string cache consists of two pointer sized fields, |
| 2963 // but times_twice_pointer_size (multiplication by 16) scale factor | 2968 // but times_twice_pointer_size (multiplication by 16) scale factor |
| 2964 // is not supported by addrmode on x64 platform. | 2969 // is not supported by addrmode on x64 platform. |
| (...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4166 | 4171 |
| 4167 // Both arguments are strings. | 4172 // Both arguments are strings. |
| 4168 // rax: first string | 4173 // rax: first string |
| 4169 // rdx: second string | 4174 // rdx: second string |
| 4170 // Check if either of the strings are empty. In that case return the other. | 4175 // Check if either of the strings are empty. In that case return the other. |
| 4171 NearLabel second_not_zero_length, both_not_zero_length; | 4176 NearLabel second_not_zero_length, both_not_zero_length; |
| 4172 __ movq(rcx, FieldOperand(rdx, String::kLengthOffset)); | 4177 __ movq(rcx, FieldOperand(rdx, String::kLengthOffset)); |
| 4173 __ SmiTest(rcx); | 4178 __ SmiTest(rcx); |
| 4174 __ j(not_zero, &second_not_zero_length); | 4179 __ j(not_zero, &second_not_zero_length); |
| 4175 // Second string is empty, result is first string which is already in rax. | 4180 // Second string is empty, result is first string which is already in rax. |
| 4176 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 4181 Counters* counters = masm->isolate()->counters(); |
| 4182 __ IncrementCounter(counters->string_add_native(), 1); |
| 4177 __ ret(2 * kPointerSize); | 4183 __ ret(2 * kPointerSize); |
| 4178 __ bind(&second_not_zero_length); | 4184 __ bind(&second_not_zero_length); |
| 4179 __ movq(rbx, FieldOperand(rax, String::kLengthOffset)); | 4185 __ movq(rbx, FieldOperand(rax, String::kLengthOffset)); |
| 4180 __ SmiTest(rbx); | 4186 __ SmiTest(rbx); |
| 4181 __ j(not_zero, &both_not_zero_length); | 4187 __ j(not_zero, &both_not_zero_length); |
| 4182 // First string is empty, result is second string which is in rdx. | 4188 // First string is empty, result is second string which is in rdx. |
| 4183 __ movq(rax, rdx); | 4189 __ movq(rax, rdx); |
| 4184 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 4190 __ IncrementCounter(counters->string_add_native(), 1); |
| 4185 __ ret(2 * kPointerSize); | 4191 __ ret(2 * kPointerSize); |
| 4186 | 4192 |
| 4187 // Both strings are non-empty. | 4193 // Both strings are non-empty. |
| 4188 // rax: first string | 4194 // rax: first string |
| 4189 // rbx: length of first string | 4195 // rbx: length of first string |
| 4190 // rcx: length of second string | 4196 // rcx: length of second string |
| 4191 // rdx: second string | 4197 // rdx: second string |
| 4192 // r8: map of first string (if flags_ == NO_STRING_ADD_FLAGS) | 4198 // r8: map of first string (if flags_ == NO_STRING_ADD_FLAGS) |
| 4193 // r9: map of second string (if flags_ == NO_STRING_ADD_FLAGS) | 4199 // r9: map of second string (if flags_ == NO_STRING_ADD_FLAGS) |
| 4194 Label string_add_flat_result, longer_than_two; | 4200 Label string_add_flat_result, longer_than_two; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 4218 | 4224 |
| 4219 // Get the two characters forming the sub string. | 4225 // Get the two characters forming the sub string. |
| 4220 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); | 4226 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); |
| 4221 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); | 4227 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); |
| 4222 | 4228 |
| 4223 // Try to lookup two character string in symbol table. If it is not found | 4229 // Try to lookup two character string in symbol table. If it is not found |
| 4224 // just allocate a new one. | 4230 // just allocate a new one. |
| 4225 Label make_two_character_string, make_flat_ascii_string; | 4231 Label make_two_character_string, make_flat_ascii_string; |
| 4226 StringHelper::GenerateTwoCharacterSymbolTableProbe( | 4232 StringHelper::GenerateTwoCharacterSymbolTableProbe( |
| 4227 masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string); | 4233 masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string); |
| 4228 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 4234 __ IncrementCounter(counters->string_add_native(), 1); |
| 4229 __ ret(2 * kPointerSize); | 4235 __ ret(2 * kPointerSize); |
| 4230 | 4236 |
| 4231 __ bind(&make_two_character_string); | 4237 __ bind(&make_two_character_string); |
| 4232 __ Set(rbx, 2); | 4238 __ Set(rbx, 2); |
| 4233 __ jmp(&make_flat_ascii_string); | 4239 __ jmp(&make_flat_ascii_string); |
| 4234 | 4240 |
| 4235 __ bind(&longer_than_two); | 4241 __ bind(&longer_than_two); |
| 4236 // Check if resulting string will be flat. | 4242 // Check if resulting string will be flat. |
| 4237 __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength)); | 4243 __ SmiCompare(rbx, Smi::FromInt(String::kMinNonFlatLength)); |
| 4238 __ j(below, &string_add_flat_result); | 4244 __ j(below, &string_add_flat_result); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4258 // Allocate an acsii cons string. | 4264 // Allocate an acsii cons string. |
| 4259 __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime); | 4265 __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime); |
| 4260 __ bind(&allocated); | 4266 __ bind(&allocated); |
| 4261 // Fill the fields of the cons string. | 4267 // Fill the fields of the cons string. |
| 4262 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); | 4268 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); |
| 4263 __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), | 4269 __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), |
| 4264 Immediate(String::kEmptyHashField)); | 4270 Immediate(String::kEmptyHashField)); |
| 4265 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); | 4271 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); |
| 4266 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); | 4272 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); |
| 4267 __ movq(rax, rcx); | 4273 __ movq(rax, rcx); |
| 4268 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 4274 __ IncrementCounter(counters->string_add_native(), 1); |
| 4269 __ ret(2 * kPointerSize); | 4275 __ ret(2 * kPointerSize); |
| 4270 __ bind(&non_ascii); | 4276 __ bind(&non_ascii); |
| 4271 // At least one of the strings is two-byte. Check whether it happens | 4277 // At least one of the strings is two-byte. Check whether it happens |
| 4272 // to contain only ascii characters. | 4278 // to contain only ascii characters. |
| 4273 // rcx: first instance type AND second instance type. | 4279 // rcx: first instance type AND second instance type. |
| 4274 // r8: first instance type. | 4280 // r8: first instance type. |
| 4275 // r9: second instance type. | 4281 // r9: second instance type. |
| 4276 __ testb(rcx, Immediate(kAsciiDataHintMask)); | 4282 __ testb(rcx, Immediate(kAsciiDataHintMask)); |
| 4277 __ j(not_zero, &ascii_data); | 4283 __ j(not_zero, &ascii_data); |
| 4278 __ xor_(r8, r9); | 4284 __ xor_(r8, r9); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4332 StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, true); | 4338 StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, true); |
| 4333 // Locate first character of second argument. | 4339 // Locate first character of second argument. |
| 4334 __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset)); | 4340 __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset)); |
| 4335 __ addq(rdx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 4341 __ addq(rdx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
| 4336 // rbx: result string | 4342 // rbx: result string |
| 4337 // rcx: next character of result | 4343 // rcx: next character of result |
| 4338 // rdx: first char of second argument | 4344 // rdx: first char of second argument |
| 4339 // rdi: length of second argument | 4345 // rdi: length of second argument |
| 4340 StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, true); | 4346 StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, true); |
| 4341 __ movq(rax, rbx); | 4347 __ movq(rax, rbx); |
| 4342 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 4348 __ IncrementCounter(counters->string_add_native(), 1); |
| 4343 __ ret(2 * kPointerSize); | 4349 __ ret(2 * kPointerSize); |
| 4344 | 4350 |
| 4345 // Handle creating a flat two byte result. | 4351 // Handle creating a flat two byte result. |
| 4346 // rax: first string - known to be two byte | 4352 // rax: first string - known to be two byte |
| 4347 // rbx: length of resulting flat string | 4353 // rbx: length of resulting flat string |
| 4348 // rdx: second string | 4354 // rdx: second string |
| 4349 // r8: instance type of first string | 4355 // r8: instance type of first string |
| 4350 // r9: instance type of first string | 4356 // r9: instance type of first string |
| 4351 __ bind(&non_ascii_string_add_flat_result); | 4357 __ bind(&non_ascii_string_add_flat_result); |
| 4352 __ and_(r9, Immediate(kAsciiStringTag)); | 4358 __ and_(r9, Immediate(kAsciiStringTag)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4369 StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, false); | 4375 StringHelper::GenerateCopyCharacters(masm, rcx, rax, rdi, false); |
| 4370 // Locate first character of second argument. | 4376 // Locate first character of second argument. |
| 4371 __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset)); | 4377 __ SmiToInteger32(rdi, FieldOperand(rdx, String::kLengthOffset)); |
| 4372 __ addq(rdx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 4378 __ addq(rdx, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
| 4373 // rbx: result string | 4379 // rbx: result string |
| 4374 // rcx: next character of result | 4380 // rcx: next character of result |
| 4375 // rdx: first char of second argument | 4381 // rdx: first char of second argument |
| 4376 // rdi: length of second argument | 4382 // rdi: length of second argument |
| 4377 StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, false); | 4383 StringHelper::GenerateCopyCharacters(masm, rcx, rdx, rdi, false); |
| 4378 __ movq(rax, rbx); | 4384 __ movq(rax, rbx); |
| 4379 __ IncrementCounter(COUNTERS->string_add_native(), 1); | 4385 __ IncrementCounter(counters->string_add_native(), 1); |
| 4380 __ ret(2 * kPointerSize); | 4386 __ ret(2 * kPointerSize); |
| 4381 | 4387 |
| 4382 // Just jump to runtime to add the two strings. | 4388 // Just jump to runtime to add the two strings. |
| 4383 __ bind(&string_add_runtime); | 4389 __ bind(&string_add_runtime); |
| 4384 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); | 4390 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); |
| 4385 | 4391 |
| 4386 if (call_builtin.is_linked()) { | 4392 if (call_builtin.is_linked()) { |
| 4387 __ bind(&call_builtin); | 4393 __ bind(&call_builtin); |
| 4388 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); | 4394 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); |
| 4389 } | 4395 } |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4784 SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 4790 SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
| 4785 } | 4791 } |
| 4786 | 4792 |
| 4787 // rax: result string | 4793 // rax: result string |
| 4788 // rcx: result length | 4794 // rcx: result length |
| 4789 // rdx: original value of rsi | 4795 // rdx: original value of rsi |
| 4790 // rdi: first character of result | 4796 // rdi: first character of result |
| 4791 // rsi: character of sub string start | 4797 // rsi: character of sub string start |
| 4792 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true); | 4798 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true); |
| 4793 __ movq(rsi, rdx); // Restore rsi. | 4799 __ movq(rsi, rdx); // Restore rsi. |
| 4794 __ IncrementCounter(COUNTERS->sub_string_native(), 1); | 4800 Counters* counters = masm->isolate()->counters(); |
| 4801 __ IncrementCounter(counters->sub_string_native(), 1); |
| 4795 __ ret(kArgumentsSize); | 4802 __ ret(kArgumentsSize); |
| 4796 | 4803 |
| 4797 __ bind(&non_ascii_flat); | 4804 __ bind(&non_ascii_flat); |
| 4798 // rax: string | 4805 // rax: string |
| 4799 // rbx: instance type & kStringRepresentationMask | kStringEncodingMask | 4806 // rbx: instance type & kStringRepresentationMask | kStringEncodingMask |
| 4800 // rcx: result string length | 4807 // rcx: result string length |
| 4801 // Check for sequential two byte string | 4808 // Check for sequential two byte string |
| 4802 __ cmpb(rbx, Immediate(kSeqStringTag | kTwoByteStringTag)); | 4809 __ cmpb(rbx, Immediate(kSeqStringTag | kTwoByteStringTag)); |
| 4803 __ j(not_equal, &runtime); | 4810 __ j(not_equal, &runtime); |
| 4804 | 4811 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4821 | 4828 |
| 4822 // rax: result string | 4829 // rax: result string |
| 4823 // rcx: result length | 4830 // rcx: result length |
| 4824 // rdx: original value of rsi | 4831 // rdx: original value of rsi |
| 4825 // rdi: first character of result | 4832 // rdi: first character of result |
| 4826 // rsi: character of sub string start | 4833 // rsi: character of sub string start |
| 4827 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false); | 4834 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false); |
| 4828 __ movq(rsi, rdx); // Restore esi. | 4835 __ movq(rsi, rdx); // Restore esi. |
| 4829 | 4836 |
| 4830 __ bind(&return_rax); | 4837 __ bind(&return_rax); |
| 4831 __ IncrementCounter(COUNTERS->sub_string_native(), 1); | 4838 __ IncrementCounter(counters->sub_string_native(), 1); |
| 4832 __ ret(kArgumentsSize); | 4839 __ ret(kArgumentsSize); |
| 4833 | 4840 |
| 4834 // Just jump to runtime to create the sub string. | 4841 // Just jump to runtime to create the sub string. |
| 4835 __ bind(&runtime); | 4842 __ bind(&runtime); |
| 4836 __ TailCallRuntime(Runtime::kSubString, 3, 1); | 4843 __ TailCallRuntime(Runtime::kSubString, 3, 1); |
| 4837 } | 4844 } |
| 4838 | 4845 |
| 4839 | 4846 |
| 4840 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, | 4847 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm, |
| 4841 Register left, | 4848 Register left, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4935 // rsp[16]: left string | 4942 // rsp[16]: left string |
| 4936 | 4943 |
| 4937 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left | 4944 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left |
| 4938 __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right | 4945 __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right |
| 4939 | 4946 |
| 4940 // Check for identity. | 4947 // Check for identity. |
| 4941 NearLabel not_same; | 4948 NearLabel not_same; |
| 4942 __ cmpq(rdx, rax); | 4949 __ cmpq(rdx, rax); |
| 4943 __ j(not_equal, ¬_same); | 4950 __ j(not_equal, ¬_same); |
| 4944 __ Move(rax, Smi::FromInt(EQUAL)); | 4951 __ Move(rax, Smi::FromInt(EQUAL)); |
| 4945 __ IncrementCounter(COUNTERS->string_compare_native(), 1); | 4952 Counters* counters = masm->isolate()->counters(); |
| 4953 __ IncrementCounter(counters->string_compare_native(), 1); |
| 4946 __ ret(2 * kPointerSize); | 4954 __ ret(2 * kPointerSize); |
| 4947 | 4955 |
| 4948 __ bind(¬_same); | 4956 __ bind(¬_same); |
| 4949 | 4957 |
| 4950 // Check that both are sequential ASCII strings. | 4958 // Check that both are sequential ASCII strings. |
| 4951 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); | 4959 __ JumpIfNotBothSequentialAsciiStrings(rdx, rax, rcx, rbx, &runtime); |
| 4952 | 4960 |
| 4953 // Inline comparison of ascii strings. | 4961 // Inline comparison of ascii strings. |
| 4954 __ IncrementCounter(COUNTERS->string_compare_native(), 1); | 4962 __ IncrementCounter(counters->string_compare_native(), 1); |
| 4955 // Drop arguments from the stack | 4963 // Drop arguments from the stack |
| 4956 __ pop(rcx); | 4964 __ pop(rcx); |
| 4957 __ addq(rsp, Immediate(2 * kPointerSize)); | 4965 __ addq(rsp, Immediate(2 * kPointerSize)); |
| 4958 __ push(rcx); | 4966 __ push(rcx); |
| 4959 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); | 4967 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); |
| 4960 | 4968 |
| 4961 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 4969 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 4962 // tagged as a small integer. | 4970 // tagged as a small integer. |
| 4963 __ bind(&runtime); | 4971 __ bind(&runtime); |
| 4964 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 4972 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5081 // Do a tail call to the rewritten stub. | 5089 // Do a tail call to the rewritten stub. |
| 5082 __ jmp(rdi); | 5090 __ jmp(rdi); |
| 5083 } | 5091 } |
| 5084 | 5092 |
| 5085 | 5093 |
| 5086 #undef __ | 5094 #undef __ |
| 5087 | 5095 |
| 5088 } } // namespace v8::internal | 5096 } } // namespace v8::internal |
| 5089 | 5097 |
| 5090 #endif // V8_TARGET_ARCH_X64 | 5098 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |