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 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 edi, | 517 edi, |
518 kDontSaveFPRegs, | 518 kDontSaveFPRegs, |
519 EMIT_REMEMBERED_SET, | 519 EMIT_REMEMBERED_SET, |
520 OMIT_SMI_CHECK); | 520 OMIT_SMI_CHECK); |
521 | 521 |
522 // Restore registers. | 522 // Restore registers. |
523 __ pop(eax); | 523 __ pop(eax); |
524 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 524 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
525 } | 525 } |
526 | 526 |
| 527 |
| 528 void StringCharLoadGenerator::Generate(MacroAssembler* masm, |
| 529 Factory* factory, |
| 530 Register string, |
| 531 Register index, |
| 532 Register result, |
| 533 Label* call_runtime) { |
| 534 // Fetch the instance type of the receiver into result register. |
| 535 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); |
| 536 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
| 537 |
| 538 // We need special handling for indirect strings. |
| 539 Label check_sequential; |
| 540 __ test(result, Immediate(kIsIndirectStringMask)); |
| 541 __ j(zero, &check_sequential); |
| 542 |
| 543 // Dispatch on the indirect string shape: slice or cons. |
| 544 Label cons_string; |
| 545 __ test(result, Immediate(kSlicedNotConsMask)); |
| 546 __ j(zero, &cons_string); |
| 547 |
| 548 // Handle slices. |
| 549 Label indirect_string_loaded; |
| 550 __ mov(result, FieldOperand(string, SlicedString::kOffsetOffset)); |
| 551 __ SmiUntag(result); |
| 552 __ add(index, result); |
| 553 __ mov(string, FieldOperand(string, SlicedString::kParentOffset)); |
| 554 __ jmp(&indirect_string_loaded); |
| 555 |
| 556 // Handle external strings. |
| 557 Label external_string, ascii_external, done; |
| 558 __ bind(&external_string); |
| 559 if (FLAG_debug_code) { |
| 560 // Assert that we do not have a cons or slice (indirect strings) here. |
| 561 // Sequential strings have already been ruled out. |
| 562 __ test(result, Immediate(kIsIndirectStringMask)); |
| 563 __ Assert(zero, "external string expected, but not found"); |
| 564 } |
| 565 __ mov(result, FieldOperand(string, ExternalString::kResourceDataOffset)); |
| 566 // Assert that the external string has not been finalized yet. |
| 567 __ test(result, result); |
| 568 __ j(zero, call_runtime); |
| 569 Register scratch = string; |
| 570 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); |
| 571 __ cmp(scratch, Immediate(factory->external_ascii_string_map())); |
| 572 __ j(equal, &ascii_external, Label::kNear); |
| 573 __ cmp(scratch, Immediate(factory->external_ascii_symbol_map())); |
| 574 __ j(equal, &ascii_external, Label::kNear); |
| 575 // Two-byte string. |
| 576 __ movzx_w(result, Operand(result, index, times_2, 0)); |
| 577 __ jmp(&done); |
| 578 __ bind(&ascii_external); |
| 579 // Ascii string. |
| 580 __ movzx_b(result, Operand(result, index, times_1, 0)); |
| 581 __ jmp(&done); |
| 582 |
| 583 // Handle conses. |
| 584 // Check whether the right hand side is the empty string (i.e. if |
| 585 // this is really a flat string in a cons string). If that is not |
| 586 // the case we would rather go to the runtime system now to flatten |
| 587 // the string. |
| 588 __ bind(&cons_string); |
| 589 __ cmp(FieldOperand(string, ConsString::kSecondOffset), |
| 590 Immediate(factory->empty_string())); |
| 591 __ j(not_equal, call_runtime); |
| 592 __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); |
| 593 |
| 594 __ bind(&indirect_string_loaded); |
| 595 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); |
| 596 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); |
| 597 |
| 598 // Check whether the string is sequential. The only non-sequential |
| 599 // shapes we support have just been unwrapped above. |
| 600 // Note that if the original string is a cons or slice with an external |
| 601 // string as underlying string, we pass that unpacked underlying string with |
| 602 // the adjusted index to the runtime function. |
| 603 __ bind(&check_sequential); |
| 604 STATIC_ASSERT(kSeqStringTag == 0); |
| 605 __ test(result, Immediate(kStringRepresentationMask)); |
| 606 __ j(not_zero, &external_string); |
| 607 |
| 608 // Dispatch on the encoding: ASCII or two-byte. |
| 609 Label ascii_string; |
| 610 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
| 611 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
| 612 __ test(result, Immediate(kStringEncodingMask)); |
| 613 __ j(not_zero, &ascii_string, Label::kNear); |
| 614 |
| 615 // Two-byte string. |
| 616 // Load the two-byte character code into the result register. |
| 617 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
| 618 __ movzx_w(result, FieldOperand(string, |
| 619 index, |
| 620 times_2, |
| 621 SeqTwoByteString::kHeaderSize)); |
| 622 __ jmp(&done, Label::kNear); |
| 623 |
| 624 // Ascii string. |
| 625 // Load the byte into the result register. |
| 626 __ bind(&ascii_string); |
| 627 __ movzx_b(result, FieldOperand(string, |
| 628 index, |
| 629 times_1, |
| 630 SeqAsciiString::kHeaderSize)); |
| 631 __ bind(&done); |
| 632 } |
| 633 |
527 #undef __ | 634 #undef __ |
528 | 635 |
529 } } // namespace v8::internal | 636 } } // namespace v8::internal |
530 | 637 |
531 #endif // V8_TARGET_ARCH_IA32 | 638 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |