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 |