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

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

Issue 7860035: Merge bleeding edge up to 9192 into the GC branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Created 9 years, 3 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/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.cc » ('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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 __ CallRuntime(Runtime::kNewFunctionContext, 1); 187 __ CallRuntime(Runtime::kNewFunctionContext, 1);
188 } 188 }
189 RecordSafepoint(Safepoint::kNoDeoptimizationIndex); 189 RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
190 // Context is returned in both eax and esi. It replaces the context 190 // Context is returned in both eax and esi. It replaces the context
191 // passed to us. It's saved in the stack and kept live in esi. 191 // passed to us. It's saved in the stack and kept live in esi.
192 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 192 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
193 193
194 // Copy parameters into context if necessary. 194 // Copy parameters into context if necessary.
195 int num_parameters = scope()->num_parameters(); 195 int num_parameters = scope()->num_parameters();
196 for (int i = 0; i < num_parameters; i++) { 196 for (int i = 0; i < num_parameters; i++) {
197 Slot* slot = scope()->parameter(i)->AsSlot(); 197 Variable* var = scope()->parameter(i);
198 if (slot != NULL && slot->type() == Slot::CONTEXT) { 198 if (var->IsContextSlot()) {
199 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 199 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
200 (num_parameters - 1 - i) * kPointerSize; 200 (num_parameters - 1 - i) * kPointerSize;
201 // Load parameter from stack. 201 // Load parameter from stack.
202 __ mov(eax, Operand(ebp, parameter_offset)); 202 __ mov(eax, Operand(ebp, parameter_offset));
203 // Store it in the context. 203 // Store it in the context.
204 int context_offset = Context::SlotOffset(slot->index()); 204 int context_offset = Context::SlotOffset(var->index());
205 __ mov(Operand(esi, context_offset), eax); 205 __ mov(Operand(esi, context_offset), eax);
206 // Update the write barrier. This clobbers eax and ebx. 206 // Update the write barrier. This clobbers eax and ebx.
207 __ RecordWriteContextSlot(esi, 207 __ RecordWriteContextSlot(esi,
208 context_offset, 208 context_offset,
209 eax, 209 eax,
210 ebx, 210 ebx,
211 kDontSaveFPRegs); 211 kDontSaveFPRegs);
212 } 212 }
213 } 213 }
214 Comment(";;; End allocate local context"); 214 Comment(";;; End allocate local context");
(...skipping 2968 matching lines...) Expand 10 before | Expand all | Expand 10 after
3183 times_pointer_size, 3183 times_pointer_size,
3184 FixedArray::kHeaderSize)); 3184 FixedArray::kHeaderSize));
3185 __ RecordWrite(elements, key, value, kSaveFPRegs); 3185 __ RecordWrite(elements, key, value, kSaveFPRegs);
3186 } 3186 }
3187 } 3187 }
3188 3188
3189 3189
3190 void LCodeGen::DoStoreKeyedFastDoubleElement( 3190 void LCodeGen::DoStoreKeyedFastDoubleElement(
3191 LStoreKeyedFastDoubleElement* instr) { 3191 LStoreKeyedFastDoubleElement* instr) {
3192 XMMRegister value = ToDoubleRegister(instr->value()); 3192 XMMRegister value = ToDoubleRegister(instr->value());
3193 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3194 Label have_value; 3193 Label have_value;
3195 3194
3196 __ ucomisd(value, value); 3195 __ ucomisd(value, value);
3197 __ j(parity_odd, &have_value); // NaN. 3196 __ j(parity_odd, &have_value); // NaN.
3198 3197
3199 ExternalReference canonical_nan_reference = 3198 ExternalReference canonical_nan_reference =
3200 ExternalReference::address_of_canonical_non_hole_nan(); 3199 ExternalReference::address_of_canonical_non_hole_nan();
3201 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); 3200 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
3202 __ bind(&have_value); 3201 __ bind(&have_value);
3203 3202
(...skipping 21 matching lines...) Expand all
3225 class DeferredStringCharCodeAt: public LDeferredCode { 3224 class DeferredStringCharCodeAt: public LDeferredCode {
3226 public: 3225 public:
3227 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) 3226 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
3228 : LDeferredCode(codegen), instr_(instr) { } 3227 : LDeferredCode(codegen), instr_(instr) { }
3229 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } 3228 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); }
3230 private: 3229 private:
3231 LStringCharCodeAt* instr_; 3230 LStringCharCodeAt* instr_;
3232 }; 3231 };
3233 3232
3234 Register string = ToRegister(instr->string()); 3233 Register string = ToRegister(instr->string());
3235 Register index = no_reg; 3234 Register index = ToRegister(instr->index());
3236 int const_index = -1;
3237 if (instr->index()->IsConstantOperand()) {
3238 const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3239 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3240 if (!Smi::IsValid(const_index)) {
3241 // Guaranteed to be out of bounds because of the assert above.
3242 // So the bounds check that must dominate this instruction must
3243 // have deoptimized already.
3244 if (FLAG_debug_code) {
3245 __ Abort("StringCharCodeAt: out of bounds index.");
3246 }
3247 // No code needs to be generated.
3248 return;
3249 }
3250 } else {
3251 index = ToRegister(instr->index());
3252 }
3253 Register result = ToRegister(instr->result()); 3235 Register result = ToRegister(instr->result());
3254 3236
3255 DeferredStringCharCodeAt* deferred = 3237 DeferredStringCharCodeAt* deferred =
3256 new DeferredStringCharCodeAt(this, instr); 3238 new DeferredStringCharCodeAt(this, instr);
3257 3239
3258 Label flat_string, ascii_string, done;
3259
3260 // Fetch the instance type of the receiver into result register. 3240 // Fetch the instance type of the receiver into result register.
3261 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); 3241 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
3262 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3242 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
3263 3243
3264 // We need special handling for non-flat strings. 3244 // We need special handling for indirect strings.
3265 STATIC_ASSERT(kSeqStringTag == 0); 3245 Label check_sequential;
3266 __ test(result, Immediate(kStringRepresentationMask)); 3246 __ test(result, Immediate(kIsIndirectStringMask));
3267 __ j(zero, &flat_string, Label::kNear); 3247 __ j(zero, &check_sequential, Label::kNear);
3268 3248
3269 // Handle non-flat strings. 3249 // Dispatch on the indirect string shape: slice or cons.
3270 __ test(result, Immediate(kIsConsStringMask)); 3250 Label cons_string;
3271 __ j(zero, deferred->entry()); 3251 __ test(result, Immediate(kSlicedNotConsMask));
3252 __ j(zero, &cons_string, Label::kNear);
3272 3253
3273 // ConsString. 3254 // Handle slices.
3255 Label indirect_string_loaded;
3256 __ mov(result, FieldOperand(string, SlicedString::kOffsetOffset));
3257 __ SmiUntag(result);
3258 __ add(index, Operand(result));
3259 __ mov(string, FieldOperand(string, SlicedString::kParentOffset));
3260 __ jmp(&indirect_string_loaded, Label::kNear);
3261
3262 // Handle conses.
3274 // Check whether the right hand side is the empty string (i.e. if 3263 // Check whether the right hand side is the empty string (i.e. if
3275 // this is really a flat string in a cons string). If that is not 3264 // this is really a flat string in a cons string). If that is not
3276 // the case we would rather go to the runtime system now to flatten 3265 // the case we would rather go to the runtime system now to flatten
3277 // the string. 3266 // the string.
3267 __ bind(&cons_string);
3278 __ cmp(FieldOperand(string, ConsString::kSecondOffset), 3268 __ cmp(FieldOperand(string, ConsString::kSecondOffset),
3279 Immediate(factory()->empty_string())); 3269 Immediate(factory()->empty_string()));
3280 __ j(not_equal, deferred->entry()); 3270 __ j(not_equal, deferred->entry());
3281 // Get the first of the two strings and load its instance type.
3282 __ mov(string, FieldOperand(string, ConsString::kFirstOffset)); 3271 __ mov(string, FieldOperand(string, ConsString::kFirstOffset));
3272
3273 __ bind(&indirect_string_loaded);
3283 __ mov(result, FieldOperand(string, HeapObject::kMapOffset)); 3274 __ mov(result, FieldOperand(string, HeapObject::kMapOffset));
3284 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset)); 3275 __ movzx_b(result, FieldOperand(result, Map::kInstanceTypeOffset));
3285 // If the first cons component is also non-flat, then go to runtime. 3276
3277 // Check whether the string is sequential. The only non-sequential
3278 // shapes we support have just been unwrapped above.
3279 __ bind(&check_sequential);
3286 STATIC_ASSERT(kSeqStringTag == 0); 3280 STATIC_ASSERT(kSeqStringTag == 0);
3287 __ test(result, Immediate(kStringRepresentationMask)); 3281 __ test(result, Immediate(kStringRepresentationMask));
3288 __ j(not_zero, deferred->entry()); 3282 __ j(not_zero, deferred->entry());
3289 3283
3290 // Check for ASCII or two-byte string. 3284 // Dispatch on the encoding: ASCII or two-byte.
3291 __ bind(&flat_string); 3285 Label ascii_string;
3292 STATIC_ASSERT(kAsciiStringTag != 0); 3286 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0);
3287 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
3293 __ test(result, Immediate(kStringEncodingMask)); 3288 __ test(result, Immediate(kStringEncodingMask));
3294 __ j(not_zero, &ascii_string, Label::kNear); 3289 __ j(not_zero, &ascii_string, Label::kNear);
3295 3290
3296 // Two-byte string. 3291 // Two-byte string.
3297 // Load the two-byte character code into the result register. 3292 // Load the two-byte character code into the result register.
3293 Label done;
3298 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 3294 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
3299 if (instr->index()->IsConstantOperand()) { 3295 __ movzx_w(result, FieldOperand(string,
3300 __ movzx_w(result, 3296 index,
3301 FieldOperand(string, 3297 times_2,
3302 SeqTwoByteString::kHeaderSize + 3298 SeqTwoByteString::kHeaderSize));
3303 (kUC16Size * const_index)));
3304 } else {
3305 __ movzx_w(result, FieldOperand(string,
3306 index,
3307 times_2,
3308 SeqTwoByteString::kHeaderSize));
3309 }
3310 __ jmp(&done, Label::kNear); 3299 __ jmp(&done, Label::kNear);
3311 3300
3312 // ASCII string. 3301 // ASCII string.
3313 // Load the byte into the result register. 3302 // Load the byte into the result register.
3314 __ bind(&ascii_string); 3303 __ bind(&ascii_string);
3315 if (instr->index()->IsConstantOperand()) { 3304 __ movzx_b(result, FieldOperand(string,
3316 __ movzx_b(result, FieldOperand(string, 3305 index,
3317 SeqAsciiString::kHeaderSize + const_index)); 3306 times_1,
3318 } else { 3307 SeqAsciiString::kHeaderSize));
3319 __ movzx_b(result, FieldOperand(string,
3320 index,
3321 times_1,
3322 SeqAsciiString::kHeaderSize));
3323 }
3324 __ bind(&done); 3308 __ bind(&done);
3325 __ bind(deferred->exit()); 3309 __ bind(deferred->exit());
3326 } 3310 }
3327 3311
3328 3312
3329 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { 3313 void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
3330 Register string = ToRegister(instr->string()); 3314 Register string = ToRegister(instr->string());
3331 Register result = ToRegister(instr->result()); 3315 Register result = ToRegister(instr->result());
3332 3316
3333 // TODO(3095996): Get rid of this. For now, we need to make the 3317 // TODO(3095996): Get rid of this. For now, we need to make the
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
4408 env->deoptimization_index()); 4392 env->deoptimization_index());
4409 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4393 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4410 } 4394 }
4411 4395
4412 4396
4413 #undef __ 4397 #undef __
4414 4398
4415 } } // namespace v8::internal 4399 } } // namespace v8::internal
4416 4400
4417 #endif // V8_TARGET_ARCH_IA32 4401 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698