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

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

Issue 7477045: Tentative implementation of string slices (hidden under the flag --string-slices). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 4 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
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 3130 matching lines...) Expand 10 before | Expand all | Expand 10 after
3141 public: 3141 public:
3142 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 3142 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
3143 : LDeferredCode(codegen), instr_(instr) { } 3143 : LDeferredCode(codegen), instr_(instr) { }
3144 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 3144 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
3145 private: 3145 private:
3146 LStringCharCodeAt* instr_; 3146 LStringCharCodeAt* instr_;
3147 }; 3147 };
3148 3148
3149 Register string = ToRegister(instr->string()); 3149 Register string = ToRegister(instr->string());
3150 Register index = no_reg; 3150 Register index = no_reg;
3151 Register offset = ToRegister(instr->TempAt(0));
3151 int const_index = -1; 3152 int const_index = -1;
3152 if (instr->index()->IsConstantOperand()) { 3153 if (instr->index()->IsConstantOperand()) {
3153 const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3154 const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3154 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 3155 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3155 if (!Smi::IsValid(const_index)) { 3156 if (!Smi::IsValid(const_index)) {
3156 // Guaranteed to be out of bounds because of the assert above. 3157 // Guaranteed to be out of bounds because of the assert above.
3157 // So the bounds check that must dominate this instruction must 3158 // So the bounds check that must dominate this instruction must
3158 // have deoptimized already. 3159 // have deoptimized already.
3159 if (FLAG_debug_code) { 3160 if (FLAG_debug_code) {
3160 __ Abort("StringCharCodeAt: out of bounds index."); 3161 __ Abort("StringCharCodeAt: out of bounds index.");
3161 } 3162 }
3162 // No code needs to be generated. 3163 // No code needs to be generated.
3163 return; 3164 return;
3164 } 3165 }
3165 } else { 3166 } else {
3166 index = ToRegister(instr->index()); 3167 index = ToRegister(instr->index());
3167 } 3168 }
3168 Register result = ToRegister(instr->result()); 3169 Register result = ToRegister(instr->result());
3169 3170
3170 DeferredStringCharCodeAt* deferred = 3171 DeferredStringCharCodeAt* deferred =
3171 new DeferredStringCharCodeAt(this, instr); 3172 new DeferredStringCharCodeAt(this, instr);
3172 3173
3173 Label flat_string, ascii_string, done; 3174 Label flat_string, ascii_string, cons_string, sliced_ascii_string, done;
3174 3175
3175 // Fetch the instance type of the receiver into result register. 3176 // Fetch the instance type of the receiver into result register.
3176 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); 3177 __ movq(result, FieldOperand(string, HeapObject::kMapOffset));
3177 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3178 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset));
3178 3179
3179 // We need special handling for non-sequential strings. 3180 // We need special handling for non-sequential strings.
3180 STATIC_ASSERT(kSeqStringTag == 0); 3181 STATIC_ASSERT(kSeqStringTag == 0);
3181 __ testb(result, Immediate(kStringRepresentationMask)); 3182 __ testb(result, Immediate(kStringRepresentationMask));
3182 __ j(zero, &flat_string, Label::kNear); 3183 __ j(zero, &flat_string, Label::kNear);
3183 3184
3184 // Handle cons strings and go to deferred code for the rest. 3185 // Handle non-flat strings.
3185 __ testb(result, Immediate(kIsConsStringMask)); 3186 __ and_(result, Immediate(kStringRepresentationMask));
3186 __ j(zero, deferred->entry()); 3187 __ cmpb(result, Immediate(kConsStringTag));
3188 __ j(equal, &cons_string, Label::kNear);
3189 __ cmpb(result, Immediate(kExternalStringTag));
3190 __ j(equal, deferred->entry());
3191
3192 // SlicedString.
3193 // Unpack slice, add offset and retrieve the result char.
3194 __ movq(offset, FieldOperand(string, SlicedString::kOffsetOffset));
3195 __ SmiToInteger32(offset, offset);
3196 if (instr->index()->IsConstantOperand()) {
3197 __ addq(offset, Immediate(const_index));
3198 } else {
3199 __ addq(offset, index);
3200 }
3201 __ movq(string, FieldOperand(string, SlicedString::kParentOffset));
3202 __ movq(result, FieldOperand(string, HeapObject::kMapOffset));
3203 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset));
3204 // Check for ASCII or two-byte string.
3205 STATIC_ASSERT(kAsciiStringTag != 0);
3206 __ testb(result, Immediate(kStringEncodingMask));
3207 __ j(not_zero, &sliced_ascii_string, Label::kNear);
3208 __ movzxwl(result, FieldOperand(string,
3209 offset,
3210 times_2,
3211 SeqTwoByteString::kHeaderSize));
3212 __ jmp(&done, Label::kNear);
3213 __ bind(&sliced_ascii_string);
3214 __ movzxbl(result, FieldOperand(string,
3215 offset,
3216 times_1,
3217 SeqAsciiString::kHeaderSize));
3218 __ jmp(&done, Label::kNear);
3187 3219
3188 // ConsString. 3220 // ConsString.
3189 // Check whether the right hand side is the empty string (i.e. if 3221 // Check whether the right hand side is the empty string (i.e. if
3190 // this is really a flat string in a cons string). If that is not 3222 // this is really a flat string in a cons string). If that is not
3191 // the case we would rather go to the runtime system now to flatten 3223 // the case we would rather go to the runtime system now to flatten
3192 // the string. 3224 // the string.
3225 __ bind(&cons_string);
3193 __ CompareRoot(FieldOperand(string, ConsString::kSecondOffset), 3226 __ CompareRoot(FieldOperand(string, ConsString::kSecondOffset),
3194 Heap::kEmptyStringRootIndex); 3227 Heap::kEmptyStringRootIndex);
3195 __ j(not_equal, deferred->entry()); 3228 __ j(not_equal, deferred->entry());
3196 // Get the first of the two strings and load its instance type. 3229 // Get the first of the two strings and load its instance type.
3197 __ movq(string, FieldOperand(string, ConsString::kFirstOffset)); 3230 __ movq(string, FieldOperand(string, ConsString::kFirstOffset));
3198 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); 3231 __ movq(result, FieldOperand(string, HeapObject::kMapOffset));
3199 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3232 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset));
3200 // If the first cons component is also non-flat, then go to runtime. 3233 // If the first cons component is also non-flat, then go to runtime.
3201 STATIC_ASSERT(kSeqStringTag == 0); 3234 STATIC_ASSERT(kSeqStringTag == 0);
3202 __ testb(result, Immediate(kStringRepresentationMask)); 3235 __ testb(result, Immediate(kStringRepresentationMask));
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after
4104 RegisterEnvironmentForDeoptimization(environment); 4137 RegisterEnvironmentForDeoptimization(environment);
4105 ASSERT(osr_pc_offset_ == -1); 4138 ASSERT(osr_pc_offset_ == -1);
4106 osr_pc_offset_ = masm()->pc_offset(); 4139 osr_pc_offset_ = masm()->pc_offset();
4107 } 4140 }
4108 4141
4109 #undef __ 4142 #undef __
4110 4143
4111 } } // namespace v8::internal 4144 } } // namespace v8::internal
4112 4145
4113 #endif // V8_TARGET_ARCH_X64 4146 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698