Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 6368009: ARM: Implement StringLength and StringCharCodeAt in the lithium-arm (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2762 matching lines...) Expand 10 before | Expand all | Expand 10 after
2773 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 2773 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
2774 ASSERT(ToRegister(instr->object()).is(r2)); 2774 ASSERT(ToRegister(instr->object()).is(r2));
2775 ASSERT(ToRegister(instr->key()).is(r1)); 2775 ASSERT(ToRegister(instr->key()).is(r1));
2776 ASSERT(ToRegister(instr->value()).is(r0)); 2776 ASSERT(ToRegister(instr->value()).is(r0));
2777 2777
2778 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 2778 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
2779 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2779 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2780 } 2780 }
2781 2781
2782 2782
2783 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
2784 class DeferredStringCharCodeAt: public LDeferredCode {
2785 public:
2786 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
2787 : LDeferredCode(codegen), instr_(instr) { }
2788 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
2789 private:
2790 LStringCharCodeAt* instr_;
2791 };
2792
2793 DeferredStringCharCodeAt* deferred
2794 = new DeferredStringCharCodeAt(this, instr);
2795
2796 Register scratch = scratch0();
2797 Register string = ToRegister(instr->string());
2798 Register index = no_reg;
2799 int const_index = -1;
2800 if (instr->index()->IsConstantOperand()) {
2801 const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2802 } else {
2803 index = ToRegister(instr->index());
2804 }
2805 Register result = ToRegister(instr->result());
2806
2807 Label flat_string, ascii_string, done;
2808
2809 // Fetch the instance type of the receiver into result register.
2810 __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset));
2811 __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
2812
2813 // We need special handling for non-flat strings.
2814 STATIC_ASSERT(kSeqStringTag == 0);
2815 __ tst(result, Operand(kStringRepresentationMask));
2816 __ b(eq, &flat_string);
2817
2818 // Handle non-flat strings.
2819 __ tst(result, Operand(kIsConsStringMask));
2820 __ b(eq, deferred->entry());
2821
2822 // ConsString.
2823 // Check whether the right hand side is the empty string (i.e. if
2824 // this is really a flat string in a cons string). If that is not
2825 // the case we would rather go to the runtime system now to flatten
2826 // the string.
2827 __ ldr(scratch, FieldMemOperand(string, ConsString::kSecondOffset));
2828 __ LoadRoot(ip, Heap::kEmptyStringRootIndex);
2829 __ cmp(scratch, ip);
2830 __ b(ne, deferred->entry());
2831 // Get the first of the two strings and load its instance type.
2832 __ ldr(string, FieldMemOperand(string, ConsString::kFirstOffset));
2833 __ ldr(result, FieldMemOperand(string, HeapObject::kMapOffset));
2834 __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
2835 // If the first cons component is also non-flat, then go to runtime.
2836 STATIC_ASSERT(kSeqStringTag == 0);
2837 __ tst(result, Operand(kStringRepresentationMask));
2838 __ b(ne, deferred->entry());
2839
2840 // Check for 1-byte or 2-byte string.
2841 __ bind(&flat_string);
2842 STATIC_ASSERT(kAsciiStringTag != 0);
2843 __ tst(result, Operand(kStringEncodingMask));
2844 __ b(ne, &ascii_string);
2845
2846 // 2-byte string.
2847 // Load the 2-byte character code into the result register.
2848 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
2849 if (instr->index()->IsConstantOperand()) {
2850 __ ldrh(result,
2851 FieldMemOperand(string,
2852 SeqTwoByteString::kHeaderSize + 2 * const_index));
2853 } else {
2854 __ add(scratch,
2855 string,
2856 Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
2857 __ ldrh(result, MemOperand(scratch, index, LSL, 1));
2858 }
2859 __ jmp(&done);
2860
2861 // ASCII string.
2862 // Load the byte into the result register.
2863 __ bind(&ascii_string);
2864 if (instr->index()->IsConstantOperand()) {
2865 __ ldrb(result, FieldMemOperand(string,
2866 SeqAsciiString::kHeaderSize + const_index));
2867 } else {
2868 __ add(scratch,
2869 string,
2870 Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
2871 __ ldrb(result, MemOperand(scratch, index));
2872 }
2873 __ bind(&done);
2874 __ bind(deferred->exit());
2875 }
2876
2877
2878 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
2879 Register string = ToRegister(instr->string());
2880 Register result = ToRegister(instr->result());
2881 Register scratch = scratch0();
2882
2883 // TODO(3095996): Get rid of this. For now, we need to make the
2884 // result register contain a valid pointer because it is already
2885 // contained in the register pointer map.
2886 __ mov(result, Operand(0));
2887
2888 __ PushSafepointRegisters();
2889 __ push(string);
2890 // Push the index as a smi.
2891 if (instr->index()->IsConstantOperand()) {
2892 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2893 __ mov(scratch, Operand(Smi::FromInt(const_index)));
2894 __ push(scratch);
2895 } else {
2896 Register index = ToRegister(instr->index());
2897 __ SmiTag(index);
2898 __ push(index);
2899 }
2900 __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt);
2901 RecordSafepointWithRegisters(
2902 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex);
2903 if (FLAG_debug_code) {
2904 __ AbortIfNotSmi(r0);
2905 }
2906 __ SmiUntag(r0);
2907 MemOperand result_stack_slot = masm()->SafepointRegisterSlot(result);
2908 __ str(r0, result_stack_slot);
2909 __ PopSafepointRegisters();
2910 }
2911
2912
2913 void LCodeGen::DoStringLength(LStringLength* instr) {
2914 Register string = ToRegister(instr->input());
2915 Register result = ToRegister(instr->result());
2916 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
2917 }
2918
2919
2783 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 2920 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
2784 LOperand* input = instr->input(); 2921 LOperand* input = instr->input();
2785 ASSERT(input->IsRegister() || input->IsStackSlot()); 2922 ASSERT(input->IsRegister() || input->IsStackSlot());
2786 LOperand* output = instr->result(); 2923 LOperand* output = instr->result();
2787 ASSERT(output->IsDoubleRegister()); 2924 ASSERT(output->IsDoubleRegister());
2788 SwVfpRegister single_scratch = double_scratch0().low(); 2925 SwVfpRegister single_scratch = double_scratch0().low();
2789 if (input->IsStackSlot()) { 2926 if (input->IsStackSlot()) {
2790 Register scratch = scratch0(); 2927 Register scratch = scratch0();
2791 __ ldr(scratch, ToMemOperand(input)); 2928 __ ldr(scratch, ToMemOperand(input));
2792 __ vmov(single_scratch, scratch); 2929 __ vmov(single_scratch, scratch);
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
3464 3601
3465 3602
3466 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 3603 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
3467 Abort("DoOsrEntry unimplemented."); 3604 Abort("DoOsrEntry unimplemented.");
3468 } 3605 }
3469 3606
3470 3607
3471 #undef __ 3608 #undef __
3472 3609
3473 } } // namespace v8::internal 3610 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698