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

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

Issue 10778029: Allow uint32 value on optimized frames if they are consumed by safe operations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: arm and x64 ports Created 8 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 for (int i = 0; i < translation_size; ++i) { 503 for (int i = 0; i < translation_size; ++i) {
504 LOperand* value = environment->values()->at(i); 504 LOperand* value = environment->values()->at(i);
505 // spilled_registers_ and spilled_double_registers_ are either 505 // spilled_registers_ and spilled_double_registers_ are either
506 // both NULL or both set. 506 // both NULL or both set.
507 if (environment->spilled_registers() != NULL && value != NULL) { 507 if (environment->spilled_registers() != NULL && value != NULL) {
508 if (value->IsRegister() && 508 if (value->IsRegister() &&
509 environment->spilled_registers()[value->index()] != NULL) { 509 environment->spilled_registers()[value->index()] != NULL) {
510 translation->MarkDuplicate(); 510 translation->MarkDuplicate();
511 AddToTranslation(translation, 511 AddToTranslation(translation,
512 environment->spilled_registers()[value->index()], 512 environment->spilled_registers()[value->index()],
513 environment->HasTaggedValueAt(i)); 513 environment->HasTaggedValueAt(i),
514 environment->HasUint32ValueAt(i));
514 } else if ( 515 } else if (
515 value->IsDoubleRegister() && 516 value->IsDoubleRegister() &&
516 environment->spilled_double_registers()[value->index()] != NULL) { 517 environment->spilled_double_registers()[value->index()] != NULL) {
517 translation->MarkDuplicate(); 518 translation->MarkDuplicate();
518 AddToTranslation( 519 AddToTranslation(
519 translation, 520 translation,
520 environment->spilled_double_registers()[value->index()], 521 environment->spilled_double_registers()[value->index()],
522 false,
521 false); 523 false);
522 } 524 }
523 } 525 }
524 526
525 AddToTranslation(translation, value, environment->HasTaggedValueAt(i)); 527 AddToTranslation(translation,
528 value,
529 environment->HasTaggedValueAt(i),
530 environment->HasUint32ValueAt(i));
526 } 531 }
527 } 532 }
528 533
529 534
530 void LCodeGen::AddToTranslation(Translation* translation, 535 void LCodeGen::AddToTranslation(Translation* translation,
531 LOperand* op, 536 LOperand* op,
532 bool is_tagged) { 537 bool is_tagged,
538 bool is_uint32) {
533 if (op == NULL) { 539 if (op == NULL) {
534 // TODO(twuerthinger): Introduce marker operands to indicate that this value 540 // TODO(twuerthinger): Introduce marker operands to indicate that this value
535 // is not present and must be reconstructed from the deoptimizer. Currently 541 // is not present and must be reconstructed from the deoptimizer. Currently
536 // this is only used for the arguments object. 542 // this is only used for the arguments object.
537 translation->StoreArgumentsObject(); 543 translation->StoreArgumentsObject();
538 } else if (op->IsStackSlot()) { 544 } else if (op->IsStackSlot()) {
539 if (is_tagged) { 545 if (is_tagged) {
540 translation->StoreStackSlot(op->index()); 546 translation->StoreStackSlot(op->index());
547 } else if (is_uint32) {
548 translation->StoreUint32StackSlot(op->index());
541 } else { 549 } else {
542 translation->StoreInt32StackSlot(op->index()); 550 translation->StoreInt32StackSlot(op->index());
543 } 551 }
544 } else if (op->IsDoubleStackSlot()) { 552 } else if (op->IsDoubleStackSlot()) {
545 translation->StoreDoubleStackSlot(op->index()); 553 translation->StoreDoubleStackSlot(op->index());
546 } else if (op->IsArgument()) { 554 } else if (op->IsArgument()) {
547 ASSERT(is_tagged); 555 ASSERT(is_tagged);
548 int src_index = GetStackSlotCount() + op->index(); 556 int src_index = GetStackSlotCount() + op->index();
549 translation->StoreStackSlot(src_index); 557 translation->StoreStackSlot(src_index);
550 } else if (op->IsRegister()) { 558 } else if (op->IsRegister()) {
551 Register reg = ToRegister(op); 559 Register reg = ToRegister(op);
552 if (is_tagged) { 560 if (is_tagged) {
553 translation->StoreRegister(reg); 561 translation->StoreRegister(reg);
562 } else if (is_uint32) {
563 translation->StoreUint32Register(reg);
554 } else { 564 } else {
555 translation->StoreInt32Register(reg); 565 translation->StoreInt32Register(reg);
556 } 566 }
557 } else if (op->IsDoubleRegister()) { 567 } else if (op->IsDoubleRegister()) {
558 DoubleRegister reg = ToDoubleRegister(op); 568 DoubleRegister reg = ToDoubleRegister(op);
559 translation->StoreDoubleRegister(reg); 569 translation->StoreDoubleRegister(reg);
560 } else if (op->IsConstantOperand()) { 570 } else if (op->IsConstantOperand()) {
561 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 571 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
562 int src_index = DefineDeoptimizationLiteral(constant->handle()); 572 int src_index = DefineDeoptimizationLiteral(constant->handle());
563 translation->StoreLiteral(src_index); 573 translation->StoreLiteral(src_index);
(...skipping 2449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3013 __ ldrsh(result, mem_operand); 3023 __ ldrsh(result, mem_operand);
3014 break; 3024 break;
3015 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3025 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3016 __ ldrh(result, mem_operand); 3026 __ ldrh(result, mem_operand);
3017 break; 3027 break;
3018 case EXTERNAL_INT_ELEMENTS: 3028 case EXTERNAL_INT_ELEMENTS:
3019 __ ldr(result, mem_operand); 3029 __ ldr(result, mem_operand);
3020 break; 3030 break;
3021 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3031 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3022 __ ldr(result, mem_operand); 3032 __ ldr(result, mem_operand);
3023 __ cmp(result, Operand(0x80000000)); 3033 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
3024 // TODO(danno): we could be more clever here, perhaps having a special 3034 __ cmp(result, Operand(0x80000000));
3025 // version of the stub that detects if the overflow case actually 3035 DeoptimizeIf(cs, instr->environment());
3026 // happens, and generate code that returns a double rather than int. 3036 }
3027 DeoptimizeIf(cs, instr->environment());
3028 break; 3037 break;
3029 case EXTERNAL_FLOAT_ELEMENTS: 3038 case EXTERNAL_FLOAT_ELEMENTS:
3030 case EXTERNAL_DOUBLE_ELEMENTS: 3039 case EXTERNAL_DOUBLE_ELEMENTS:
3031 case FAST_HOLEY_DOUBLE_ELEMENTS: 3040 case FAST_HOLEY_DOUBLE_ELEMENTS:
3032 case FAST_HOLEY_ELEMENTS: 3041 case FAST_HOLEY_ELEMENTS:
3033 case FAST_HOLEY_SMI_ELEMENTS: 3042 case FAST_HOLEY_SMI_ELEMENTS:
3034 case FAST_DOUBLE_ELEMENTS: 3043 case FAST_DOUBLE_ELEMENTS:
3035 case FAST_ELEMENTS: 3044 case FAST_ELEMENTS:
3036 case FAST_SMI_ELEMENTS: 3045 case FAST_SMI_ELEMENTS:
3037 case DICTIONARY_ELEMENTS: 3046 case DICTIONARY_ELEMENTS:
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after
4255 Register scratch = scratch0(); 4264 Register scratch = scratch0();
4256 __ ldr(scratch, ToMemOperand(input)); 4265 __ ldr(scratch, ToMemOperand(input));
4257 __ vmov(single_scratch, scratch); 4266 __ vmov(single_scratch, scratch);
4258 } else { 4267 } else {
4259 __ vmov(single_scratch, ToRegister(input)); 4268 __ vmov(single_scratch, ToRegister(input));
4260 } 4269 }
4261 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4270 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4262 } 4271 }
4263 4272
4264 4273
4274 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4275 LOperand* input = instr->InputAt(0);
4276 LOperand* output = instr->result();
4277
4278 SwVfpRegister flt_scratch = double_scratch0().low();
4279 __ vmov(flt_scratch, ToRegister(input));
4280 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
4281 }
4282
4283
4265 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4284 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4266 class DeferredNumberTagI: public LDeferredCode { 4285 class DeferredNumberTagI: public LDeferredCode {
4267 public: 4286 public:
4268 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4287 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4269 : LDeferredCode(codegen), instr_(instr) { } 4288 : LDeferredCode(codegen), instr_(instr) { }
4270 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 4289 virtual void Generate() {
4290 codegen()->DoDeferredNumberTagI(instr_, SIGNED_INT32);
4291 }
4271 virtual LInstruction* instr() { return instr_; } 4292 virtual LInstruction* instr() { return instr_; }
4272 private: 4293 private:
4273 LNumberTagI* instr_; 4294 LNumberTagI* instr_;
4274 }; 4295 };
4275 4296
4276 Register src = ToRegister(instr->InputAt(0)); 4297 Register src = ToRegister(instr->InputAt(0));
4277 Register dst = ToRegister(instr->result()); 4298 Register dst = ToRegister(instr->result());
4278 4299
4279 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4300 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4280 __ SmiTag(dst, src, SetCC); 4301 __ SmiTag(dst, src, SetCC);
4281 __ b(vs, deferred->entry()); 4302 __ b(vs, deferred->entry());
4282 __ bind(deferred->exit()); 4303 __ bind(deferred->exit());
4283 } 4304 }
4284 4305
4285 4306
4286 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 4307 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4308 class DeferredNumberTagU: public LDeferredCode {
4309 public:
4310 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4311 : LDeferredCode(codegen), instr_(instr) { }
4312 virtual void Generate() {
4313 codegen()->DoDeferredNumberTagI(instr_, UNSIGNED_INT32);
4314 }
4315 virtual LInstruction* instr() { return instr_; }
4316 private:
4317 LNumberTagU* instr_;
4318 };
4319
4320 LOperand* input = instr->InputAt(0);
4321 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4322 Register reg = ToRegister(input);
4323
4324 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4325 __ cmp(reg, Operand(Smi::kMaxValue));
4326 __ b(hi, deferred->entry());
4327 __ SmiTag(reg, reg);
4328 __ bind(deferred->exit());
4329 }
4330
4331
4332 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4333 IntegerSignedness signedness) {
4287 Label slow; 4334 Label slow;
4288 Register src = ToRegister(instr->InputAt(0)); 4335 Register src = ToRegister(instr->InputAt(0));
4289 Register dst = ToRegister(instr->result()); 4336 Register dst = ToRegister(instr->result());
4290 DoubleRegister dbl_scratch = double_scratch0(); 4337 DoubleRegister dbl_scratch = double_scratch0();
4291 SwVfpRegister flt_scratch = dbl_scratch.low(); 4338 SwVfpRegister flt_scratch = dbl_scratch.low();
4292 4339
4293 // Preserve the value of all registers. 4340 // Preserve the value of all registers.
4294 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4341 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4295 4342
4296 // There was overflow, so bits 30 and 31 of the original integer
4297 // disagree. Try to allocate a heap number in new space and store
4298 // the value in there. If that fails, call the runtime system.
4299 Label done; 4343 Label done;
4300 if (dst.is(src)) { 4344 if (signedness == SIGNED_INT32) {
4301 __ SmiUntag(src, dst); 4345 // There was overflow, so bits 30 and 31 of the original integer
4302 __ eor(src, src, Operand(0x80000000)); 4346 // disagree. Try to allocate a heap number in new space and store
4347 // the value in there. If that fails, call the runtime system.
4348 if (dst.is(src)) {
4349 __ SmiUntag(src, dst);
4350 __ eor(src, src, Operand(0x80000000));
4351 }
4352 __ vmov(flt_scratch, src);
4353 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4354 } else {
4355 __ vmov(flt_scratch, src);
4356 __ vcvt_f64_u32(dbl_scratch, flt_scratch);
4303 } 4357 }
4304 __ vmov(flt_scratch, src); 4358
4305 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4306 if (FLAG_inline_new) { 4359 if (FLAG_inline_new) {
4307 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 4360 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
4308 __ AllocateHeapNumber(r5, r3, r4, r6, &slow); 4361 __ AllocateHeapNumber(r5, r3, r4, r6, &slow);
4309 __ Move(dst, r5); 4362 __ Move(dst, r5);
4310 __ b(&done); 4363 __ b(&done);
4311 } 4364 }
4312 4365
4313 // Slow case: Call the runtime system to do the number allocation. 4366 // Slow case: Call the runtime system to do the number allocation.
4314 __ bind(&slow); 4367 __ bind(&slow);
4315 4368
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after
5527 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5580 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5528 __ ldr(result, FieldMemOperand(scratch, 5581 __ ldr(result, FieldMemOperand(scratch,
5529 FixedArray::kHeaderSize - kPointerSize)); 5582 FixedArray::kHeaderSize - kPointerSize));
5530 __ bind(&done); 5583 __ bind(&done);
5531 } 5584 }
5532 5585
5533 5586
5534 #undef __ 5587 #undef __
5535 5588
5536 } } // namespace v8::internal 5589 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/simulator-arm.cc » ('j') | src/deoptimizer.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698