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

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

Issue 6243008: Support StringCharCodeAt in hydrogen/lithium. (Closed)
Patch Set: Addressed Florian's 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
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 2633 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 2644 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
2645 ASSERT(ToRegister(instr->object()).is(edx)); 2645 ASSERT(ToRegister(instr->object()).is(edx));
2646 ASSERT(ToRegister(instr->key()).is(ecx)); 2646 ASSERT(ToRegister(instr->key()).is(ecx));
2647 ASSERT(ToRegister(instr->value()).is(eax)); 2647 ASSERT(ToRegister(instr->value()).is(eax));
2648 2648
2649 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 2649 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
2650 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2650 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2651 } 2651 }
2652 2652
2653 2653
2654 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
2655 class DeferredStringCharCodeAt: public LDeferredCode {
2656 public:
2657 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
2658 : LDeferredCode(codegen), instr_(instr) { }
2659 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
2660 private:
2661 LStringCharCodeAt* instr_;
2662 };
2663
2664 DeferredStringCharCodeAt* deferred = new DeferredStringCharCodeAt(this,
2665 instr);
2666
2667 Register string = ToRegister(instr->string());
2668 Register index = no_reg;
2669 int const_index = -1;
2670 if (instr->index()->IsConstantOperand()) {
2671 const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2672 } else {
2673 index = ToRegister(instr->index());
2674 }
2675 Register result = ToRegister(instr->result());
2676
2677 NearLabel flat_string, ascii_string, done;
2678
2679 // Fetch the instance type of the receiver into result register.
2680 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
2681 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
2682
2683 // We need special handling for non-flat strings.
2684 STATIC_ASSERT(kSeqStringTag == 0);
2685 __ test(result, Immediate(kStringRepresentationMask));
2686 __ j(zero, &flat_string);
2687
2688 // Handle non-flat strings.
2689 __ test(result, Immediate(kIsConsStringMask));
2690 __ j(zero, deferred->entry());
2691
2692 // ConsString.
2693 // Check whether the right hand side is the empty string (i.e. if
2694 // this is really a flat string in a cons string). If that is not
2695 // the case we would rather go to the runtime system now to flatten
2696 // the string.
2697 __ cmp(FieldOperand(string, ConsString::kSecondOffset),
2698 Immediate(Factory::empty_string()));
2699 __ j(not_equal, deferred->entry());
2700 // Get the first of the two strings and load its instance type.
2701 __ mov(string, FieldOperand(string, ConsString::kFirstOffset));
2702 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
2703 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
2704 // If the first cons component is also non-flat, then go to runtime.
2705 STATIC_ASSERT(kSeqStringTag == 0);
2706 __ test(result, Immediate(kStringRepresentationMask));
2707 __ j(not_zero, deferred->entry());
2708
2709 // Check for 1-byte or 2-byte string.
2710 __ bind(&flat_string);
2711 STATIC_ASSERT(kAsciiStringTag != 0);
2712 __ test(result, Immediate(kStringEncodingMask));
2713 __ j(not_zero, &ascii_string);
2714
2715 // 2-byte string.
2716 // Load the 2-byte character code into the result register.
2717 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
2718 if (index.is_valid()) {
2719 __ movzx_w(result, FieldOperand(string,
2720 index, times_2,
2721 SeqTwoByteString::kHeaderSize));
2722 } else {
2723 __ movzx_w(result, FieldOperand(
2724 string, SeqTwoByteString::kHeaderSize + 2 * const_index));
2725 }
2726 __ jmp(&done);
2727
2728 // ASCII string.
2729 // Load the byte into the result register.
2730 __ bind(&ascii_string);
2731 if (index.is_valid()) {
2732 __ movzx_b(result, FieldOperand(string,
2733 index, times_1,
2734 SeqAsciiString::kHeaderSize));
2735 } else {
2736 __ movzx_b(result, FieldOperand(string,
2737 SeqAsciiString::kHeaderSize + const_index));
2738 }
2739 __ bind(&done);
2740 __ bind(deferred->exit());
2741 }
2742
2743
2744 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
2745 Register string = ToRegister(instr->string());
2746 Register result = ToRegister(instr->result());
2747
2748 // TODO(3095996): Get rid of this. For now, we need to make the
2749 // result register contain a valid pointer because it is already
2750 // contained in the register pointer map.
2751 __ Set(result, Immediate(0));
2752
2753 __ PushSafepointRegisters();
2754 __ push(string);
2755 // Push the index as a smi.
2756 if (instr->index()->IsConstantOperand()) {
2757 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2758 __ push(Immediate(Smi::FromInt(const_index)));
2759 } else {
2760 Register index = ToRegister(instr->index());
2761 __ SmiTag(index);
2762 __ push(index);
2763 }
2764 __ CallRuntimeSaveDoubles(Runtime::kStringCharCodeAt);
2765 RecordSafepointWithRegisters(
2766 instr->pointer_map(), 2, Safepoint::kNoDeoptimizationIndex);
2767 if (FLAG_debug_code) {
2768 __ AbortIfNotSmi(eax);
2769 }
2770 __ SmiUntag(eax);
2771 __ mov(Operand(esp, EspIndexForPushAll(result) * kPointerSize), eax);
2772 __ PopSafepointRegisters();
2773 }
2774
2775
2776 void LCodeGen::DoStringLength(LStringLength* instr) {
2777 Register string = ToRegister(instr->string());
2778 Register result = ToRegister(instr->result());
2779 __ mov(result, FieldOperand(string, String::kLengthOffset));
2780 }
2781
2782
2654 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 2783 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
2655 LOperand* input = instr->InputAt(0); 2784 LOperand* input = instr->InputAt(0);
2656 ASSERT(input->IsRegister() || input->IsStackSlot()); 2785 ASSERT(input->IsRegister() || input->IsStackSlot());
2657 LOperand* output = instr->result(); 2786 LOperand* output = instr->result();
2658 ASSERT(output->IsDoubleRegister()); 2787 ASSERT(output->IsDoubleRegister());
2659 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 2788 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
2660 } 2789 }
2661 2790
2662 2791
2663 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 2792 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
3070 } 3199 }
3071 3200
3072 3201
3073 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { 3202 void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
3074 Register input = ToRegister(instr->InputAt(0)); 3203 Register input = ToRegister(instr->InputAt(0));
3075 Register temp = ToRegister(instr->TempAt(0)); 3204 Register temp = ToRegister(instr->TempAt(0));
3076 InstanceType first = instr->hydrogen()->first(); 3205 InstanceType first = instr->hydrogen()->first();
3077 InstanceType last = instr->hydrogen()->last(); 3206 InstanceType last = instr->hydrogen()->last();
3078 3207
3079 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); 3208 __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
3080 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3081 static_cast<int8_t>(first));
3082 3209
3083 // If there is only one type in the interval check for equality. 3210 // If there is only one type in the interval check for equality.
3084 if (first == last) { 3211 if (first == last) {
3212 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3213 static_cast<int8_t>(first));
3085 DeoptimizeIf(not_equal, instr->environment()); 3214 DeoptimizeIf(not_equal, instr->environment());
3086 } else { 3215 } else if (first == FIRST_STRING_TYPE && last == LAST_STRING_TYPE) {
3216 // String has a dedicated bit in instance type.
3217 __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), kIsNotStringMask);
3218 DeoptimizeIf(not_zero, instr->environment());
3219 } else {
3220 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3221 static_cast<int8_t>(first));
3087 DeoptimizeIf(below, instr->environment()); 3222 DeoptimizeIf(below, instr->environment());
3088 // Omit check for the last type. 3223 // Omit check for the last type.
3089 if (last != LAST_TYPE) { 3224 if (last != LAST_TYPE) {
3090 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), 3225 __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset),
3091 static_cast<int8_t>(last)); 3226 static_cast<int8_t>(last));
3092 DeoptimizeIf(above, instr->environment()); 3227 DeoptimizeIf(above, instr->environment());
3093 } 3228 }
3094 } 3229 }
3095 } 3230 }
3096 3231
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
3450 ASSERT(osr_pc_offset_ == -1); 3585 ASSERT(osr_pc_offset_ == -1);
3451 osr_pc_offset_ = masm()->pc_offset(); 3586 osr_pc_offset_ = masm()->pc_offset();
3452 } 3587 }
3453 3588
3454 3589
3455 #undef __ 3590 #undef __
3456 3591
3457 } } // namespace v8::internal 3592 } } // namespace v8::internal
3458 3593
3459 #endif // V8_TARGET_ARCH_IA32 3594 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698