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

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

Issue 6304001: Support StringCharCodeAt in hydrogen/lithium. (Closed)
Patch Set: 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
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 2664 matching lines...) Expand 10 before | Expand all | Expand 10 after
2675 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 2675 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
2676 ASSERT(ToRegister(instr->object()).is(edx)); 2676 ASSERT(ToRegister(instr->object()).is(edx));
2677 ASSERT(ToRegister(instr->key()).is(ecx)); 2677 ASSERT(ToRegister(instr->key()).is(ecx));
2678 ASSERT(ToRegister(instr->value()).is(eax)); 2678 ASSERT(ToRegister(instr->value()).is(eax));
2679 2679
2680 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 2680 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
2681 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2681 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2682 } 2682 }
2683 2683
2684 2684
2685 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
2686 class DeferredStringCharCodeAt: public LDeferredCode {
2687 public:
2688 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
2689 : LDeferredCode(codegen), instr_(instr) { }
2690 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
2691 private:
2692 LStringCharCodeAt* instr_;
2693 };
2694
2695 DeferredStringCharCodeAt* deferred = new DeferredStringCharCodeAt(this,
2696 instr);
2697
2698 Register string = ToRegister(instr->string());
2699 Register index = no_reg;
2700 int const_index = -1;
2701 if (instr->index()->IsConstantOperand()) {
2702 const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2703 } else {
2704 index = ToRegister(instr->index());
2705 }
2706 Register result = ToRegister(instr->result());
2707
2708 NearLabel flat_string, ascii_string, done;
2709
2710 // Fetch the instance type of the receiver into result register.
2711 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
2712 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
2713
2714 // We need special handling for non-flat strings.
2715 STATIC_ASSERT(kSeqStringTag == 0);
2716 __ test(result, Immediate(kStringRepresentationMask));
2717 __ j(zero, &flat_string);
2718
2719 // Handle non-flat strings.
2720 __ test(result, Immediate(kIsConsStringMask));
2721 __ j(zero, deferred->entry());
2722
2723 // ConsString.
2724 // Check whether the right hand side is the empty string (i.e. if
2725 // this is really a flat string in a cons string). If that is not
2726 // the case we would rather go to the runtime system now to flatten
2727 // the string.
2728 __ cmp(FieldOperand(string, ConsString::kSecondOffset),
2729 Immediate(Factory::empty_string()));
2730 __ j(not_equal, deferred->entry());
2731 // Get the first of the two strings and load its instance type.
2732 __ mov(string, FieldOperand(string, ConsString::kFirstOffset));
2733 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
2734 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
2735 // If the first cons component is also non-flat, then go to runtime.
2736 STATIC_ASSERT(kSeqStringTag == 0);
2737 __ test(result, Immediate(kStringRepresentationMask));
2738 __ j(not_zero, deferred->entry());
2739
2740 // Check for 1-byte or 2-byte string.
2741 __ bind(&flat_string);
2742 STATIC_ASSERT(kAsciiStringTag != 0);
2743 __ test(result, Immediate(kStringEncodingMask));
2744 __ j(not_zero, &ascii_string);
2745
2746 // 2-byte string.
2747 // Load the 2-byte character code into the result register.
2748 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
2749 if (index.is_valid()) {
2750 __ movzx_w(result, FieldOperand(string,
2751 index, times_2,
2752 SeqTwoByteString::kHeaderSize));
2753 } else {
2754 __ movzx_w(result, FieldOperand(
2755 string, SeqTwoByteString::kHeaderSize + 2 * const_index));
2756 }
2757 __ jmp(&done);
2758
2759 // ASCII string.
2760 // Load the byte into the result register.
2761 __ bind(&ascii_string);
2762 if (index.is_valid()) {
2763 __ movzx_b(result, FieldOperand(string,
2764 index, times_1,
2765 SeqAsciiString::kHeaderSize));
2766 } else {
2767 __ movzx_b(result, FieldOperand(string,
2768 SeqAsciiString::kHeaderSize + const_index));
2769 }
2770 __ bind(&done);
2771 __ bind(deferred->exit());
2772 }
2773
2774
2775 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
2776 Register string = ToRegister(instr->string());
2777 Register result = ToRegister(instr->result());
2778
2779 // TODO(3095996): Get rid of this. For now, we need to make the
2780 // result register contain a valid pointer because it is already
2781 // contained in the register pointer map.
2782 __ Set(result, Immediate(0));
2783
2784 __ PushSafepointRegisters();
2785 __ push(string);
2786 // Push the index as a smi.
2787 if (instr->index()->IsConstantOperand()) {
2788 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2789 __ push(Immediate(Smi::FromInt(const_index)));
2790 } else {
2791 Register index = ToRegister(instr->index());
2792 __ SmiTag(index);
2793 __ push(index);
2794 }
2795 __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt);
2796 RecordSafepointWithRegisters(
2797 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex);
2798 if (FLAG_debug_code) {
2799 __ AbortIfNotSmi(eax);
2800 }
2801 __ SmiUntag(eax);
2802 __ mov(Operand(esp, EspIndexForPushAll(result) * kPointerSize), eax);
2803 __ PopSafepointRegisters();
2804 }
2805
2806
2807 void LCodeGen::DoStringLength(LStringLength* instr) {
2808 Register string = ToRegister(instr->input());
2809 Register result = ToRegister(instr->result());
2810 __ mov(result, FieldOperand(string, String::kLengthOffset));
2811 }
2812
2813
2685 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 2814 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
2686 LOperand* input = instr->input(); 2815 LOperand* input = instr->input();
2687 ASSERT(input->IsRegister() || input->IsStackSlot()); 2816 ASSERT(input->IsRegister() || input->IsStackSlot());
2688 LOperand* output = instr->result(); 2817 LOperand* output = instr->result();
2689 ASSERT(output->IsDoubleRegister()); 2818 ASSERT(output->IsDoubleRegister());
2690 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 2819 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
2691 } 2820 }
2692 2821
2693 2822
2694 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 2823 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
3101 } 3230 }
3102 3231
3103 3232
3104 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 3233 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
3105 Register input = ToRegister(instr->input()); 3234 Register input = ToRegister(instr->input());
3106 Register temp = ToRegister(instr->temp()); 3235 Register temp = ToRegister(instr->temp());
3107 InstanceType first = instr->hydrogen()->first(); 3236 InstanceType first = instr->hydrogen()->first();
3108 InstanceType last = instr->hydrogen()->last(); 3237 InstanceType last = instr->hydrogen()->last();
3109 3238
3110 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 3239 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
3111 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3112 static_cast<int8_t>(first));
3113 3240
3114 // If there is only one type in the interval check for equality. 3241 // If there is only one type in the interval check for equality.
3115 if (first == last) { 3242 if (first == last) {
3243 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3244 static_cast<int8_t>(first));
3116 DeoptimizeIf(not_equal, instr->environment()); 3245 DeoptimizeIf(not_equal, instr->environment());
3117 } else { 3246 } else if (first == FIRST_STRING_TYPE && last == LAST_STRING_TYPE) {
3247 // String has a dedicated bit in instance type.
3248 __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), kIsNotStringMask);
3249 DeoptimizeIf(not_zero, instr->environment());
3250 } else {
3251 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3252 static_cast<int8_t>(first));
3118 DeoptimizeIf(below, instr->environment()); 3253 DeoptimizeIf(below, instr->environment());
3119 // Omit check for the last type. 3254 // Omit check for the last type.
3120 if (last != LAST_TYPE) { 3255 if (last != LAST_TYPE) {
3121 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 3256 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3122 static_cast<int8_t>(last)); 3257 static_cast<int8_t>(last));
3123 DeoptimizeIf(above, instr->environment()); 3258 DeoptimizeIf(above, instr->environment());
3124 } 3259 }
3125 } 3260 }
3126 } 3261 }
3127 3262
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 ASSERT(osr_pc_offset_ == -1); 3616 ASSERT(osr_pc_offset_ == -1);
3482 osr_pc_offset_ = masm()->pc_offset(); 3617 osr_pc_offset_ = masm()->pc_offset();
3483 } 3618 }
3484 3619
3485 3620
3486 #undef __ 3621 #undef __
3487 3622
3488 } } // namespace v8::internal 3623 } } // namespace v8::internal
3489 3624
3490 #endif // V8_TARGET_ARCH_IA32 3625 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698