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

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: Some more suggested changes. 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 3129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3140 class DeferredStringCharCodeAt: public LDeferredCode { 3140 class DeferredStringCharCodeAt: public LDeferredCode {
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 = ToRegister(instr->index());
3151 int const_index = -1;
3152 if (instr->index()->IsConstantOperand()) {
3153 const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3154 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3155 if (!Smi::IsValid(const_index)) {
3156 // Guaranteed to be out of bounds because of the assert above.
3157 // So the bounds check that must dominate this instruction must
3158 // have deoptimized already.
3159 if (FLAG_debug_code) {
3160 __ Abort("StringCharCodeAt: out of bounds index.");
3161 }
3162 // No code needs to be generated.
3163 return;
3164 }
3165 } else {
3166 index = ToRegister(instr->index());
3167 }
3168 Register result = ToRegister(instr->result()); 3151 Register result = ToRegister(instr->result());
3169 3152
3170 DeferredStringCharCodeAt* deferred = 3153 DeferredStringCharCodeAt* deferred =
3171 new DeferredStringCharCodeAt(this, instr); 3154 new DeferredStringCharCodeAt(this, instr);
3172 3155
3173 Label flat_string, ascii_string, done;
3174
3175 // Fetch the instance type of the receiver into result register. 3156 // Fetch the instance type of the receiver into result register.
3176 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); 3157 __ movq(result, FieldOperand(string, HeapObject::kMapOffset));
3177 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3158 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset));
3178 3159
3179 // We need special handling for non-sequential strings. 3160 // We need special handling for indirect strings.
3180 STATIC_ASSERT(kSeqStringTag == 0); 3161 Label check_sequential;
3181 __ testb(result, Immediate(kStringRepresentationMask)); 3162 __ testb(result, Immediate(kIsIndirectStringMask));
3182 __ j(zero, &flat_string, Label::kNear); 3163 __ j(zero, &check_sequential, Label::kNear);
3183 3164
3184 // Handle cons strings and go to deferred code for the rest. 3165 // Dispatch on the indirect string shape: slice or cons.
3185 __ testb(result, Immediate(kIsConsStringMask)); 3166 Label cons_string;
3186 __ j(zero, deferred->entry()); 3167 const uint32_t kSlicedNotConsMask = kSlicedStringTag & ~kConsStringTag;
3168 ASSERT(IsPowerOf2(kSlicedNotConsMask) && kSlicedNotConsMask != 0);
3169 __ testb(result, Immediate(kSlicedNotConsMask));
3170 __ j(zero, &cons_string, Label::kNear);
3187 3171
3188 // ConsString. 3172 // Handle slices.
3173 Label indirect_string_loaded;
3174 __ SmiToInteger32(result, FieldOperand(string, SlicedString::kOffsetOffset));
3175 __ addq(index, result);
3176 __ movq(string, FieldOperand(string, SlicedString::kParentOffset));
3177 __ jmp(&indirect_string_loaded, Label::kNear);
3178
3179 // Handle conses.
3189 // Check whether the right hand side is the empty string (i.e. if 3180 // 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 3181 // 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 3182 // the case we would rather go to the runtime system now to flatten
3192 // the string. 3183 // the string.
3184 __ bind(&cons_string);
3193 __ CompareRoot(FieldOperand(string, ConsString::kSecondOffset), 3185 __ CompareRoot(FieldOperand(string, ConsString::kSecondOffset),
3194 Heap::kEmptyStringRootIndex); 3186 Heap::kEmptyStringRootIndex);
3195 __ j(not_equal, deferred->entry()); 3187 __ j(not_equal, deferred->entry());
3196 // Get the first of the two strings and load its instance type.
3197 __ movq(string, FieldOperand(string, ConsString::kFirstOffset)); 3188 __ movq(string, FieldOperand(string, ConsString::kFirstOffset));
3189
3190 __ bind(&indirect_string_loaded);
3198 __ movq(result, FieldOperand(string, HeapObject::kMapOffset)); 3191 __ movq(result, FieldOperand(string, HeapObject::kMapOffset));
3199 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3192 __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset));
3200 // If the first cons component is also non-flat, then go to runtime. 3193
3194 // Check whether the string is sequential. The only non-sequential
3195 // shapes we support have just been unwrapped above.
3196 __ bind(&check_sequential);
3201 STATIC_ASSERT(kSeqStringTag == 0); 3197 STATIC_ASSERT(kSeqStringTag == 0);
3202 __ testb(result, Immediate(kStringRepresentationMask)); 3198 __ testb(result, Immediate(kStringRepresentationMask));
3203 __ j(not_zero, deferred->entry()); 3199 __ j(not_zero, deferred->entry());
3204 3200
3205 // Check for ASCII or two-byte string. 3201 // Dispatch on the encoding: ASCII or two-byte.
3206 __ bind(&flat_string); 3202 Label ascii_string;
3207 STATIC_ASSERT(kAsciiStringTag != 0); 3203 STATIC_ASSERT(kAsciiStringTag != 0);
3208 __ testb(result, Immediate(kStringEncodingMask)); 3204 __ testb(result, Immediate(kStringEncodingMask));
3209 __ j(not_zero, &ascii_string, Label::kNear); 3205 __ j(not_zero, &ascii_string, Label::kNear);
3210 3206
3211 // Two-byte string. 3207 // Two-byte string.
3212 // Load the two-byte character code into the result register. 3208 // Load the two-byte character code into the result register.
3209 Label done;
3213 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 3210 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
3214 if (instr->index()->IsConstantOperand()) { 3211 __ movzxwl(result, FieldOperand(string,
3215 __ movzxwl(result, 3212 index,
3216 FieldOperand(string, 3213 times_2,
3217 SeqTwoByteString::kHeaderSize + 3214 SeqTwoByteString::kHeaderSize));
3218 (kUC16Size * const_index)));
3219 } else {
3220 __ movzxwl(result, FieldOperand(string,
3221 index,
3222 times_2,
3223 SeqTwoByteString::kHeaderSize));
3224 }
3225 __ jmp(&done, Label::kNear); 3215 __ jmp(&done, Label::kNear);
3226 3216
3227 // ASCII string. 3217 // ASCII string.
3228 // Load the byte into the result register. 3218 // Load the byte into the result register.
3229 __ bind(&ascii_string); 3219 __ bind(&ascii_string);
3230 if (instr->index()->IsConstantOperand()) { 3220 __ movzxbl(result, FieldOperand(string,
3231 __ movzxbl(result, FieldOperand(string, 3221 index,
3232 SeqAsciiString::kHeaderSize + const_index)); 3222 times_1,
3233 } else { 3223 SeqAsciiString::kHeaderSize));
3234 __ movzxbl(result, FieldOperand(string,
3235 index,
3236 times_1,
3237 SeqAsciiString::kHeaderSize));
3238 }
3239 __ bind(&done); 3224 __ bind(&done);
3240 __ bind(deferred->exit()); 3225 __ bind(deferred->exit());
3241 } 3226 }
3242 3227
3243 3228
3244 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 3229 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
3245 Register string = ToRegister(instr->string()); 3230 Register string = ToRegister(instr->string());
3246 Register result = ToRegister(instr->result()); 3231 Register result = ToRegister(instr->result());
3247 3232
3248 // TODO(3095996): Get rid of this. For now, we need to make the 3233 // TODO(3095996): Get rid of this. For now, we need to make the
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after
4104 RegisterEnvironmentForDeoptimization(environment); 4089 RegisterEnvironmentForDeoptimization(environment);
4105 ASSERT(osr_pc_offset_ == -1); 4090 ASSERT(osr_pc_offset_ == -1);
4106 osr_pc_offset_ = masm()->pc_offset(); 4091 osr_pc_offset_ = masm()->pc_offset();
4107 } 4092 }
4108 4093
4109 #undef __ 4094 #undef __
4110 4095
4111 } } // namespace v8::internal 4096 } } // namespace v8::internal
4112 4097
4113 #endif // V8_TARGET_ARCH_X64 4098 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698