OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 8982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8993 // First string is empty, result is second string which is in rdx. | 8993 // First string is empty, result is second string which is in rdx. |
8994 __ movq(rax, rdx); | 8994 __ movq(rax, rdx); |
8995 __ IncrementCounter(&Counters::string_add_native, 1); | 8995 __ IncrementCounter(&Counters::string_add_native, 1); |
8996 __ ret(2 * kPointerSize); | 8996 __ ret(2 * kPointerSize); |
8997 | 8997 |
8998 // Both strings are non-empty. | 8998 // Both strings are non-empty. |
8999 // rax: first string | 8999 // rax: first string |
9000 // rbx: length of first string | 9000 // rbx: length of first string |
9001 // rcx: length of second string | 9001 // rcx: length of second string |
9002 // rdx: second string | 9002 // rdx: second string |
9003 // r8: instance type of first string if string check was performed above | 9003 // r8: map of first string if string check was performed above |
9004 // r9: instance type of first string if string check was performed above | 9004 // r9: map of second string if string check was performed above |
9005 Label string_add_flat_result; | 9005 Label string_add_flat_result, longer_than_two; |
9006 __ bind(&both_not_zero_length); | 9006 __ bind(&both_not_zero_length); |
9007 // Look at the length of the result of adding the two strings. | 9007 |
9008 __ addl(rbx, rcx); | |
9009 // Use the runtime system when adding two one character strings, as it | |
9010 // contains optimizations for this specific case using the symbol table. | |
9011 __ cmpl(rbx, Immediate(2)); | |
9012 __ j(equal, &string_add_runtime); | |
9013 // If arguments where known to be strings, maps are not loaded to r8 and r9 | 9008 // If arguments where known to be strings, maps are not loaded to r8 and r9 |
9014 // by the code above. | 9009 // by the code above. |
9015 if (!string_check_) { | 9010 if (!string_check_) { |
9016 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset)); | 9011 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset)); |
9017 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); | 9012 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); |
9018 } | 9013 } |
9019 // Get the instance types of the two strings as they will be needed soon. | 9014 // Get the instance types of the two strings as they will be needed soon. |
9020 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset)); | 9015 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset)); |
9021 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); | 9016 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); |
| 9017 |
| 9018 // Look at the length of the result of adding the two strings. |
| 9019 __ addl(rbx, rcx); |
| 9020 // Use the runtime system when adding two one character strings, as it |
| 9021 // contains optimizations for this specific case using the symbol table. |
| 9022 __ cmpl(rbx, Immediate(2)); |
| 9023 __ j(not_equal, &longer_than_two); |
| 9024 |
| 9025 // Check that both strings are non-external ascii strings. |
| 9026 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, |
| 9027 &string_add_runtime); |
| 9028 |
| 9029 // Get the two characters forming the sub string. |
| 9030 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); |
| 9031 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); |
| 9032 |
| 9033 // Try to lookup two character string in symbol table. If it is not found |
| 9034 // just allocate a new one. |
| 9035 Label make_two_character_string, make_flat_ascii_string; |
| 9036 GenerateTwoCharacterSymbolTableProbe(masm, rbx, rcx, r14, r12, rdi, r15, |
| 9037 &make_two_character_string); |
| 9038 __ IncrementCounter(&Counters::string_add_native, 1); |
| 9039 __ ret(2 * kPointerSize); |
| 9040 |
| 9041 __ bind(&make_two_character_string); |
| 9042 __ Set(rbx, 2); |
| 9043 __ jmp(&make_flat_ascii_string); |
| 9044 |
| 9045 __ bind(&longer_than_two); |
9022 // Check if resulting string will be flat. | 9046 // Check if resulting string will be flat. |
9023 __ cmpl(rbx, Immediate(String::kMinNonFlatLength)); | 9047 __ cmpl(rbx, Immediate(String::kMinNonFlatLength)); |
9024 __ j(below, &string_add_flat_result); | 9048 __ j(below, &string_add_flat_result); |
9025 // Handle exceptionally long strings in the runtime system. | 9049 // Handle exceptionally long strings in the runtime system. |
9026 ASSERT((String::kMaxLength & 0x80000000) == 0); | 9050 ASSERT((String::kMaxLength & 0x80000000) == 0); |
9027 __ cmpl(rbx, Immediate(String::kMaxLength)); | 9051 __ cmpl(rbx, Immediate(String::kMaxLength)); |
9028 __ j(above, &string_add_runtime); | 9052 __ j(above, &string_add_runtime); |
9029 | 9053 |
9030 // If result is not supposed to be flat, allocate a cons string object. If | 9054 // If result is not supposed to be flat, allocate a cons string object. If |
9031 // both strings are ascii the result is an ascii cons string. | 9055 // both strings are ascii the result is an ascii cons string. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9078 // ebx: length of resulting flat string | 9102 // ebx: length of resulting flat string |
9079 // rdx: second string | 9103 // rdx: second string |
9080 // r8: instance type of first string | 9104 // r8: instance type of first string |
9081 // r9: instance type of second string | 9105 // r9: instance type of second string |
9082 Label non_ascii_string_add_flat_result; | 9106 Label non_ascii_string_add_flat_result; |
9083 ASSERT(kStringEncodingMask == kAsciiStringTag); | 9107 ASSERT(kStringEncodingMask == kAsciiStringTag); |
9084 __ testl(r8, Immediate(kAsciiStringTag)); | 9108 __ testl(r8, Immediate(kAsciiStringTag)); |
9085 __ j(zero, &non_ascii_string_add_flat_result); | 9109 __ j(zero, &non_ascii_string_add_flat_result); |
9086 __ testl(r9, Immediate(kAsciiStringTag)); | 9110 __ testl(r9, Immediate(kAsciiStringTag)); |
9087 __ j(zero, &string_add_runtime); | 9111 __ j(zero, &string_add_runtime); |
| 9112 |
| 9113 __ bind(&make_flat_ascii_string); |
9088 // Both strings are ascii strings. As they are short they are both flat. | 9114 // Both strings are ascii strings. As they are short they are both flat. |
9089 __ AllocateAsciiString(rcx, rbx, rdi, r14, r15, &string_add_runtime); | 9115 __ AllocateAsciiString(rcx, rbx, rdi, r14, r15, &string_add_runtime); |
9090 // rcx: result string | 9116 // rcx: result string |
9091 __ movq(rbx, rcx); | 9117 __ movq(rbx, rcx); |
9092 // Locate first character of result. | 9118 // Locate first character of result. |
9093 __ addq(rcx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 9119 __ addq(rcx, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
9094 // Locate first character of first argument | 9120 // Locate first character of first argument |
9095 __ movl(rdi, FieldOperand(rax, String::kLengthOffset)); | 9121 __ movl(rdi, FieldOperand(rax, String::kLengthOffset)); |
9096 __ addq(rax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 9122 __ addq(rax, Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
9097 // rax: first char of first argument | 9123 // rax: first char of first argument |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9228 __ movb(kScratchRegister, Operand(src, 0)); | 9254 __ movb(kScratchRegister, Operand(src, 0)); |
9229 __ movb(Operand(dest, 0), kScratchRegister); | 9255 __ movb(Operand(dest, 0), kScratchRegister); |
9230 __ addq(src, Immediate(1)); | 9256 __ addq(src, Immediate(1)); |
9231 __ addq(dest, Immediate(1)); | 9257 __ addq(dest, Immediate(1)); |
9232 __ subq(count, Immediate(1)); | 9258 __ subq(count, Immediate(1)); |
9233 __ j(not_zero, &loop); | 9259 __ j(not_zero, &loop); |
9234 | 9260 |
9235 __ bind(&done); | 9261 __ bind(&done); |
9236 } | 9262 } |
9237 | 9263 |
| 9264 void StringStubBase::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, |
| 9265 Register c1, |
| 9266 Register c2, |
| 9267 Register scratch1, |
| 9268 Register scratch2, |
| 9269 Register scratch3, |
| 9270 Register scratch4, |
| 9271 Label* not_found) { |
| 9272 // Register scratch3 is the general scratch register in this function. |
| 9273 Register scratch = scratch3; |
| 9274 |
| 9275 // Make sure that both characters are not digits as such strings has a |
| 9276 // different hash algorithm. Don't try to look for these in the symbol table. |
| 9277 Label not_array_index; |
| 9278 __ movq(scratch, c1); |
| 9279 __ subq(scratch, Immediate(static_cast<int>('0'))); |
| 9280 __ cmpq(scratch, Immediate(static_cast<int>('9' - '0'))); |
| 9281 __ j(above, ¬_array_index); |
| 9282 __ movq(scratch, c2); |
| 9283 __ subq(scratch, Immediate(static_cast<int>('0'))); |
| 9284 __ cmpq(scratch, Immediate(static_cast<int>('9' - '0'))); |
| 9285 __ j(below_equal, not_found); |
| 9286 |
| 9287 __ bind(¬_array_index); |
| 9288 // Calculate the two character string hash. |
| 9289 Register hash = scratch1; |
| 9290 GenerateHashInit(masm, hash, c1, scratch); |
| 9291 GenerateHashAddCharacter(masm, hash, c2, scratch); |
| 9292 GenerateHashGetHash(masm, hash, scratch); |
| 9293 |
| 9294 // Collect the two characters in a register. |
| 9295 Register chars = c1; |
| 9296 __ shl(c2, Immediate(kBitsPerByte)); |
| 9297 __ orl(chars, c2); |
| 9298 |
| 9299 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
| 9300 // hash: hash of two character string. |
| 9301 |
| 9302 // Load the symbol table. |
| 9303 Register symbol_table = c2; |
| 9304 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); |
| 9305 |
| 9306 // Calculate capacity mask from the symbol table capacity. |
| 9307 Register mask = scratch2; |
| 9308 __ movq(mask, FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); |
| 9309 __ SmiToInteger32(mask, mask); |
| 9310 __ decl(mask); |
| 9311 |
| 9312 Register undefined = scratch4; |
| 9313 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); |
| 9314 |
| 9315 // Registers |
| 9316 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
| 9317 // hash: hash of two character string (32-bit int) |
| 9318 // symbol_table: symbol table |
| 9319 // mask: capacity mask (32-bit int) |
| 9320 // undefined: undefined value |
| 9321 // scratch: - |
| 9322 |
| 9323 // Perform a number of probes in the symbol table. |
| 9324 static const int kProbes = 4; |
| 9325 Label found_in_symbol_table; |
| 9326 Label next_probe[kProbes]; |
| 9327 for (int i = 0; i < kProbes; i++) { |
| 9328 // Calculate entry in symbol table. |
| 9329 __ movl(scratch, hash); |
| 9330 if (i > 0) { |
| 9331 __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i))); |
| 9332 } |
| 9333 __ andl(scratch, mask); |
| 9334 |
| 9335 // Load the entry from the symble table. |
| 9336 Register candidate = scratch; // Scratch register contains candidate. |
| 9337 ASSERT_EQ(1, SymbolTable::kEntrySize); |
| 9338 __ movq(candidate, |
| 9339 FieldOperand(symbol_table, |
| 9340 scratch, |
| 9341 times_pointer_size, |
| 9342 SymbolTable::kElementsStartOffset)); |
| 9343 |
| 9344 // If entry is undefined no string with this hash can be found. |
| 9345 __ cmpq(candidate, undefined); |
| 9346 __ j(equal, not_found); |
| 9347 |
| 9348 // If length is not 2 the string is not a candidate. |
| 9349 __ cmpl(FieldOperand(candidate, String::kLengthOffset), Immediate(2)); |
| 9350 __ j(not_equal, &next_probe[i]); |
| 9351 |
| 9352 // We use kScratchRegister as a temporary register in assumption that |
| 9353 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly |
| 9354 Register temp = kScratchRegister; |
| 9355 |
| 9356 // Check that the candidate is a non-external ascii string. |
| 9357 __ movq(temp, FieldOperand(candidate, HeapObject::kMapOffset)); |
| 9358 __ movzxbl(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); |
| 9359 __ JumpIfInstanceTypeIsNotSequentialAscii( |
| 9360 temp, temp, &next_probe[i]); |
| 9361 |
| 9362 // Check if the two characters match. |
| 9363 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize)); |
| 9364 __ andl(temp, Immediate(0x0000ffff)); |
| 9365 __ cmpl(chars, temp); |
| 9366 __ j(equal, &found_in_symbol_table); |
| 9367 __ bind(&next_probe[i]); |
| 9368 } |
| 9369 |
| 9370 // No matching 2 character string found by probing. |
| 9371 __ jmp(not_found); |
| 9372 |
| 9373 // Scratch register contains result when we fall through to here. |
| 9374 Register result = scratch; |
| 9375 __ bind(&found_in_symbol_table); |
| 9376 if (!result.is(rax)) { |
| 9377 __ movq(rax, result); |
| 9378 } |
| 9379 } |
| 9380 |
| 9381 |
| 9382 void StringStubBase::GenerateHashInit(MacroAssembler* masm, |
| 9383 Register hash, |
| 9384 Register character, |
| 9385 Register scratch) { |
| 9386 // hash = character + (character << 10); |
| 9387 __ movl(hash, character); |
| 9388 __ shll(hash, Immediate(10)); |
| 9389 __ addl(hash, character); |
| 9390 // hash ^= hash >> 6; |
| 9391 __ movl(scratch, hash); |
| 9392 __ sarl(scratch, Immediate(6)); |
| 9393 __ xorl(hash, scratch); |
| 9394 } |
| 9395 |
| 9396 |
| 9397 void StringStubBase::GenerateHashAddCharacter(MacroAssembler* masm, |
| 9398 Register hash, |
| 9399 Register character, |
| 9400 Register scratch) { |
| 9401 // hash += character; |
| 9402 __ addl(hash, character); |
| 9403 // hash += hash << 10; |
| 9404 __ movl(scratch, hash); |
| 9405 __ shll(scratch, Immediate(10)); |
| 9406 __ addl(hash, scratch); |
| 9407 // hash ^= hash >> 6; |
| 9408 __ movl(scratch, hash); |
| 9409 __ sarl(scratch, Immediate(6)); |
| 9410 __ xorl(hash, scratch); |
| 9411 } |
| 9412 |
| 9413 |
| 9414 void StringStubBase::GenerateHashGetHash(MacroAssembler* masm, |
| 9415 Register hash, |
| 9416 Register scratch) { |
| 9417 // hash += hash << 3; |
| 9418 __ movl(scratch, hash); |
| 9419 __ shll(scratch, Immediate(3)); |
| 9420 __ addl(hash, scratch); |
| 9421 // hash ^= hash >> 11; |
| 9422 __ movl(scratch, hash); |
| 9423 __ sarl(scratch, Immediate(11)); |
| 9424 __ xorl(hash, scratch); |
| 9425 // hash += hash << 15; |
| 9426 __ movl(scratch, hash); |
| 9427 __ shll(scratch, Immediate(15)); |
| 9428 __ addl(hash, scratch); |
| 9429 |
| 9430 // if (hash == 0) hash = 27; |
| 9431 Label hash_not_zero; |
| 9432 __ testl(hash, hash); |
| 9433 __ j(not_zero, &hash_not_zero); |
| 9434 __ movl(hash, Immediate(27)); |
| 9435 __ bind(&hash_not_zero); |
| 9436 } |
9238 | 9437 |
9239 void SubStringStub::Generate(MacroAssembler* masm) { | 9438 void SubStringStub::Generate(MacroAssembler* masm) { |
9240 Label runtime; | 9439 Label runtime; |
9241 | 9440 |
9242 // Stack frame on entry. | 9441 // Stack frame on entry. |
9243 // rsp[0]: return address | 9442 // rsp[0]: return address |
9244 // rsp[8]: to | 9443 // rsp[8]: to |
9245 // rsp[16]: from | 9444 // rsp[16]: from |
9246 // rsp[24]: string | 9445 // rsp[24]: string |
9247 | 9446 |
9248 const int kToOffset = 1 * kPointerSize; | 9447 const int kToOffset = 1 * kPointerSize; |
9249 const int kFromOffset = kToOffset + kPointerSize; | 9448 const int kFromOffset = kToOffset + kPointerSize; |
9250 const int kStringOffset = kFromOffset + kPointerSize; | 9449 const int kStringOffset = kFromOffset + kPointerSize; |
9251 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset; | 9450 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset; |
9252 | 9451 |
9253 // Make sure first argument is a string. | 9452 // Make sure first argument is a string. |
9254 __ movq(rax, Operand(rsp, kStringOffset)); | 9453 __ movq(rax, Operand(rsp, kStringOffset)); |
9255 ASSERT_EQ(0, kSmiTag); | 9454 ASSERT_EQ(0, kSmiTag); |
9256 __ testl(rax, Immediate(kSmiTagMask)); | 9455 __ testl(rax, Immediate(kSmiTagMask)); |
9257 __ j(zero, &runtime); | 9456 __ j(zero, &runtime); |
9258 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx); | 9457 Condition is_string = masm->IsObjectStringType(rax, rbx, rbx); |
9259 __ j(NegateCondition(is_string), &runtime); | 9458 __ j(NegateCondition(is_string), &runtime); |
9260 | 9459 |
9261 // rax: string | 9460 // rax: string |
9262 // rbx: instance type | 9461 // rbx: instance type |
9263 // Calculate length of sub string using the smi values. | 9462 // Calculate length of sub string using the smi values. |
| 9463 Label result_longer_than_two; |
9264 __ movq(rcx, Operand(rsp, kToOffset)); | 9464 __ movq(rcx, Operand(rsp, kToOffset)); |
9265 __ movq(rdx, Operand(rsp, kFromOffset)); | 9465 __ movq(rdx, Operand(rsp, kFromOffset)); |
9266 __ JumpIfNotBothPositiveSmi(rcx, rdx, &runtime); | 9466 __ JumpIfNotBothPositiveSmi(rcx, rdx, &runtime); |
9267 | 9467 |
9268 __ SmiSub(rcx, rcx, rdx, NULL); // Overflow doesn't happen. | 9468 __ SmiSub(rcx, rcx, rdx, NULL); // Overflow doesn't happen. |
9269 __ j(negative, &runtime); | 9469 __ j(negative, &runtime); |
9270 // Handle sub-strings of length 2 and less in the runtime system. | 9470 // Special handling of sub-strings of length 1 and 2. One character strings |
| 9471 // are handled in the runtime system (looked up in the single character |
| 9472 // cache). Two character strings are looked for in the symbol cache. |
9271 __ SmiToInteger32(rcx, rcx); | 9473 __ SmiToInteger32(rcx, rcx); |
9272 __ cmpl(rcx, Immediate(2)); | 9474 __ cmpl(rcx, Immediate(2)); |
9273 __ j(below_equal, &runtime); | 9475 __ j(greater, &result_longer_than_two); |
| 9476 __ j(less, &runtime); |
| 9477 |
| 9478 // Sub string of length 2 requested. |
| 9479 // rax: string |
| 9480 // rbx: instance type |
| 9481 // rcx: sub string length (value is 2) |
| 9482 // rdx: from index (smi) |
| 9483 __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &runtime); |
| 9484 |
| 9485 // Get the two characters forming the sub string. |
| 9486 __ SmiToInteger32(rdx, rdx); // From index is no longer smi. |
| 9487 __ movzxbq(rbx, FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize)); |
| 9488 __ movzxbq(rcx, |
| 9489 FieldOperand(rax, rdx, times_1, SeqAsciiString::kHeaderSize + 1)); |
| 9490 |
| 9491 // Try to lookup two character string in symbol table. |
| 9492 Label make_two_character_string; |
| 9493 GenerateTwoCharacterSymbolTableProbe(masm, rbx, rcx, rax, rdx, rdi, r14, |
| 9494 &make_two_character_string); |
| 9495 __ ret(3 * kPointerSize); |
| 9496 |
| 9497 __ bind(&make_two_character_string); |
| 9498 // Setup registers for allocating the two character string. |
| 9499 __ movq(rax, Operand(rsp, kStringOffset)); |
| 9500 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 9501 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); |
| 9502 __ Set(rcx, 2); |
| 9503 |
| 9504 __ bind(&result_longer_than_two); |
9274 | 9505 |
9275 // rax: string | 9506 // rax: string |
9276 // rbx: instance type | 9507 // rbx: instance type |
9277 // rcx: result string length | 9508 // rcx: result string length |
9278 // Check for flat ascii string | 9509 // Check for flat ascii string |
9279 Label non_ascii_flat; | 9510 Label non_ascii_flat; |
9280 __ and_(rbx, Immediate(kStringRepresentationMask | kStringEncodingMask)); | 9511 __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &non_ascii_flat); |
9281 __ cmpb(rbx, Immediate(kSeqStringTag | kAsciiStringTag)); | |
9282 __ j(not_equal, &non_ascii_flat); | |
9283 | 9512 |
9284 // Allocate the result. | 9513 // Allocate the result. |
9285 __ AllocateAsciiString(rax, rcx, rbx, rdx, rdi, &runtime); | 9514 __ AllocateAsciiString(rax, rcx, rbx, rdx, rdi, &runtime); |
9286 | 9515 |
9287 // rax: result string | 9516 // rax: result string |
9288 // rcx: result string length | 9517 // rcx: result string length |
9289 __ movq(rdx, rsi); // esi used by following code. | 9518 __ movq(rdx, rsi); // esi used by following code. |
9290 // Locate first character of result. | 9519 // Locate first character of result. |
9291 __ lea(rdi, FieldOperand(rax, SeqAsciiString::kHeaderSize)); | 9520 __ lea(rdi, FieldOperand(rax, SeqAsciiString::kHeaderSize)); |
9292 // Load string argument and locate character of sub string start. | 9521 // Load string argument and locate character of sub string start. |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9558 // Call the function from C++. | 9787 // Call the function from C++. |
9559 return FUNCTION_CAST<ModuloFunction>(buffer); | 9788 return FUNCTION_CAST<ModuloFunction>(buffer); |
9560 } | 9789 } |
9561 | 9790 |
9562 #endif | 9791 #endif |
9563 | 9792 |
9564 | 9793 |
9565 #undef __ | 9794 #undef __ |
9566 | 9795 |
9567 } } // namespace v8::internal | 9796 } } // namespace v8::internal |
OLD | NEW |