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

Side by Side Diff: src/ia32/lithium-codegen-ia32.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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 for (int i = 0; i < translation_size; ++i) { 442 for (int i = 0; i < translation_size; ++i) {
443 LOperand* value = environment->values()->at(i); 443 LOperand* value = environment->values()->at(i);
444 // spilled_registers_ and spilled_double_registers_ are either 444 // spilled_registers_ and spilled_double_registers_ are either
445 // both NULL or both set. 445 // both NULL or both set.
446 if (environment->spilled_registers() != NULL && value != NULL) { 446 if (environment->spilled_registers() != NULL && value != NULL) {
447 if (value->IsRegister() && 447 if (value->IsRegister() &&
448 environment->spilled_registers()[value->index()] != NULL) { 448 environment->spilled_registers()[value->index()] != NULL) {
449 translation->MarkDuplicate(); 449 translation->MarkDuplicate();
450 AddToTranslation(translation, 450 AddToTranslation(translation,
451 environment->spilled_registers()[value->index()], 451 environment->spilled_registers()[value->index()],
452 environment->HasTaggedValueAt(i)); 452 environment->HasTaggedValueAt(i),
453 environment->HasUint32ValueAt(i));
453 } else if ( 454 } else if (
454 value->IsDoubleRegister() && 455 value->IsDoubleRegister() &&
455 environment->spilled_double_registers()[value->index()] != NULL) { 456 environment->spilled_double_registers()[value->index()] != NULL) {
456 translation->MarkDuplicate(); 457 translation->MarkDuplicate();
457 AddToTranslation( 458 AddToTranslation(
458 translation, 459 translation,
459 environment->spilled_double_registers()[value->index()], 460 environment->spilled_double_registers()[value->index()],
461 false,
460 false); 462 false);
461 } 463 }
462 } 464 }
463 465
464 AddToTranslation(translation, value, environment->HasTaggedValueAt(i)); 466 AddToTranslation(translation,
467 value,
468 environment->HasTaggedValueAt(i),
469 environment->HasUint32ValueAt(i));
465 } 470 }
466 } 471 }
467 472
468 473
469 void LCodeGen::AddToTranslation(Translation* translation, 474 void LCodeGen::AddToTranslation(Translation* translation,
470 LOperand* op, 475 LOperand* op,
471 bool is_tagged) { 476 bool is_tagged,
477 bool is_uint32) {
472 if (op == NULL) { 478 if (op == NULL) {
473 // TODO(twuerthinger): Introduce marker operands to indicate that this value 479 // TODO(twuerthinger): Introduce marker operands to indicate that this value
474 // is not present and must be reconstructed from the deoptimizer. Currently 480 // is not present and must be reconstructed from the deoptimizer. Currently
475 // this is only used for the arguments object. 481 // this is only used for the arguments object.
476 translation->StoreArgumentsObject(); 482 translation->StoreArgumentsObject();
477 } else if (op->IsStackSlot()) { 483 } else if (op->IsStackSlot()) {
478 if (is_tagged) { 484 if (is_tagged) {
479 translation->StoreStackSlot(op->index()); 485 translation->StoreStackSlot(op->index());
486 } else if (is_uint32) {
487 translation->StoreUint32StackSlot(op->index());
480 } else { 488 } else {
481 translation->StoreInt32StackSlot(op->index()); 489 translation->StoreInt32StackSlot(op->index());
482 } 490 }
483 } else if (op->IsDoubleStackSlot()) { 491 } else if (op->IsDoubleStackSlot()) {
484 translation->StoreDoubleStackSlot(op->index()); 492 translation->StoreDoubleStackSlot(op->index());
485 } else if (op->IsArgument()) { 493 } else if (op->IsArgument()) {
486 ASSERT(is_tagged); 494 ASSERT(is_tagged);
487 int src_index = GetStackSlotCount() + op->index(); 495 int src_index = GetStackSlotCount() + op->index();
488 translation->StoreStackSlot(src_index); 496 translation->StoreStackSlot(src_index);
489 } else if (op->IsRegister()) { 497 } else if (op->IsRegister()) {
490 Register reg = ToRegister(op); 498 Register reg = ToRegister(op);
491 if (is_tagged) { 499 if (is_tagged) {
492 translation->StoreRegister(reg); 500 translation->StoreRegister(reg);
501 } else if (is_uint32) {
502 translation->StoreUint32Register(reg);
493 } else { 503 } else {
494 translation->StoreInt32Register(reg); 504 translation->StoreInt32Register(reg);
495 } 505 }
496 } else if (op->IsDoubleRegister()) { 506 } else if (op->IsDoubleRegister()) {
497 XMMRegister reg = ToDoubleRegister(op); 507 XMMRegister reg = ToDoubleRegister(op);
498 translation->StoreDoubleRegister(reg); 508 translation->StoreDoubleRegister(reg);
499 } else if (op->IsConstantOperand()) { 509 } else if (op->IsConstantOperand()) {
500 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 510 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
501 int src_index = DefineDeoptimizationLiteral(constant->handle()); 511 int src_index = DefineDeoptimizationLiteral(constant->handle());
502 translation->StoreLiteral(src_index); 512 translation->StoreLiteral(src_index);
(...skipping 2325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2828 __ movsx_w(result, operand); 2838 __ movsx_w(result, operand);
2829 break; 2839 break;
2830 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 2840 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2831 __ movzx_w(result, operand); 2841 __ movzx_w(result, operand);
2832 break; 2842 break;
2833 case EXTERNAL_INT_ELEMENTS: 2843 case EXTERNAL_INT_ELEMENTS:
2834 __ mov(result, operand); 2844 __ mov(result, operand);
2835 break; 2845 break;
2836 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2846 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2837 __ mov(result, operand); 2847 __ mov(result, operand);
2838 __ test(result, Operand(result)); 2848 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2839 // TODO(danno): we could be more clever here, perhaps having a special 2849 __ test(result, Operand(result));
2840 // version of the stub that detects if the overflow case actually 2850 DeoptimizeIf(negative, instr->environment());
2841 // happens, and generate code that returns a double rather than int. 2851 }
2842 DeoptimizeIf(negative, instr->environment());
2843 break; 2852 break;
2844 case EXTERNAL_FLOAT_ELEMENTS: 2853 case EXTERNAL_FLOAT_ELEMENTS:
2845 case EXTERNAL_DOUBLE_ELEMENTS: 2854 case EXTERNAL_DOUBLE_ELEMENTS:
2846 case FAST_SMI_ELEMENTS: 2855 case FAST_SMI_ELEMENTS:
2847 case FAST_ELEMENTS: 2856 case FAST_ELEMENTS:
2848 case FAST_DOUBLE_ELEMENTS: 2857 case FAST_DOUBLE_ELEMENTS:
2849 case FAST_HOLEY_SMI_ELEMENTS: 2858 case FAST_HOLEY_SMI_ELEMENTS:
2850 case FAST_HOLEY_ELEMENTS: 2859 case FAST_HOLEY_ELEMENTS:
2851 case FAST_HOLEY_DOUBLE_ELEMENTS: 2860 case FAST_HOLEY_DOUBLE_ELEMENTS:
2852 case DICTIONARY_ELEMENTS: 2861 case DICTIONARY_ELEMENTS:
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after
4051 4060
4052 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4061 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4053 LOperand* input = instr->InputAt(0); 4062 LOperand* input = instr->InputAt(0);
4054 ASSERT(input->IsRegister() || input->IsStackSlot()); 4063 ASSERT(input->IsRegister() || input->IsStackSlot());
4055 LOperand* output = instr->result(); 4064 LOperand* output = instr->result();
4056 ASSERT(output->IsDoubleRegister()); 4065 ASSERT(output->IsDoubleRegister());
4057 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 4066 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
4058 } 4067 }
4059 4068
4060 4069
4070 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4071 LOperand* input = instr->InputAt(0);
4072 LOperand* output = instr->result();
4073 LOperand* temp = instr->TempAt(0);
4074
4075 __ LoadUint32(ToDoubleRegister(output),
4076 ToRegister(input),
4077 ToDoubleRegister(temp));
4078 }
4079
4080
4061 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4081 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4062 class DeferredNumberTagI: public LDeferredCode { 4082 class DeferredNumberTagI: public LDeferredCode {
4063 public: 4083 public:
4064 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) 4084 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
4065 : LDeferredCode(codegen), instr_(instr) { } 4085 : LDeferredCode(codegen), instr_(instr) { }
4066 virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); } 4086 virtual void Generate() {
4087 codegen()->DoDeferredNumberTagI(instr_, SIGNED_INT32);
4088 }
4067 virtual LInstruction* instr() { return instr_; } 4089 virtual LInstruction* instr() { return instr_; }
4068 private: 4090 private:
4069 LNumberTagI* instr_; 4091 LNumberTagI* instr_;
4070 }; 4092 };
4071 4093
4072 LOperand* input = instr->InputAt(0); 4094 LOperand* input = instr->InputAt(0);
4073 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4095 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4074 Register reg = ToRegister(input); 4096 Register reg = ToRegister(input);
4075 4097
4076 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); 4098 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr);
4077 __ SmiTag(reg); 4099 __ SmiTag(reg);
4078 __ j(overflow, deferred->entry()); 4100 __ j(overflow, deferred->entry());
4079 __ bind(deferred->exit()); 4101 __ bind(deferred->exit());
4080 } 4102 }
4081 4103
4082 4104
4083 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { 4105 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4106 class DeferredNumberTagU: public LDeferredCode {
4107 public:
4108 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4109 : LDeferredCode(codegen), instr_(instr) { }
4110 virtual void Generate() {
4111 codegen()->DoDeferredNumberTagI(instr_, UNSIGNED_INT32);
4112 }
4113 virtual LInstruction* instr() { return instr_; }
4114 private:
4115 LNumberTagU* instr_;
4116 };
4117
4118 LOperand* input = instr->InputAt(0);
4119 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4120 Register reg = ToRegister(input);
4121
4122 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4123 __ cmp(reg, Immediate(Smi::kMaxValue));
4124 __ j(above, deferred->entry());
4125 __ SmiTag(reg);
4126 __ bind(deferred->exit());
4127 }
4128
4129
4130 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4131 IntegerSignedness signedness) {
4084 Label slow; 4132 Label slow;
4085 Register reg = ToRegister(instr->InputAt(0)); 4133 Register reg = ToRegister(instr->InputAt(0));
4086 Register tmp = reg.is(eax) ? ecx : eax; 4134 Register tmp = reg.is(eax) ? ecx : eax;
4087 4135
4088 // Preserve the value of all registers. 4136 // Preserve the value of all registers.
4089 PushSafepointRegistersScope scope(this); 4137 PushSafepointRegistersScope scope(this);
4090 4138
4091 // There was overflow, so bits 30 and 31 of the original integer
4092 // disagree. Try to allocate a heap number in new space and store
4093 // the value in there. If that fails, call the runtime system.
4094 Label done; 4139 Label done;
4095 __ SmiUntag(reg); 4140
4096 __ xor_(reg, 0x80000000); 4141 if (signedness == SIGNED_INT32) {
4097 __ cvtsi2sd(xmm0, Operand(reg)); 4142 // There was overflow, so bits 30 and 31 of the original integer
4143 // disagree. Try to allocate a heap number in new space and store
4144 // the value in there. If that fails, call the runtime system.
4145 __ SmiUntag(reg);
4146 __ xor_(reg, 0x80000000);
4147 __ cvtsi2sd(xmm0, Operand(reg));
4148 } else {
4149 __ LoadUint32(xmm0, reg, xmm1);
4150 }
4151
4098 if (FLAG_inline_new) { 4152 if (FLAG_inline_new) {
4099 __ AllocateHeapNumber(reg, tmp, no_reg, &slow); 4153 __ AllocateHeapNumber(reg, tmp, no_reg, &slow);
4100 __ jmp(&done, Label::kNear); 4154 __ jmp(&done, Label::kNear);
4101 } 4155 }
4102 4156
4103 // Slow case: Call the runtime system to do the number allocation. 4157 // Slow case: Call the runtime system to do the number allocation.
4104 __ bind(&slow); 4158 __ bind(&slow);
4105 4159
4106 // TODO(3095996): Put a valid pointer value in the stack slot where the result 4160 // TODO(3095996): Put a valid pointer value in the stack slot where the result
4107 // register is stored, as this register is in the pointer map, but contains an 4161 // register is stored, as this register is in the pointer map, but contains an
(...skipping 1314 matching lines...) Expand 10 before | Expand all | Expand 10 after
5422 FixedArray::kHeaderSize - kPointerSize)); 5476 FixedArray::kHeaderSize - kPointerSize));
5423 __ bind(&done); 5477 __ bind(&done);
5424 } 5478 }
5425 5479
5426 5480
5427 #undef __ 5481 #undef __
5428 5482
5429 } } // namespace v8::internal 5483 } } // namespace v8::internal
5430 5484
5431 #endif // V8_TARGET_ARCH_IA32 5485 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698