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

Side by Side Diff: src/x64/lithium-codegen-x64.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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 for (int i = 0; i < translation_size; ++i) { 390 for (int i = 0; i < translation_size; ++i) {
391 LOperand* value = environment->values()->at(i); 391 LOperand* value = environment->values()->at(i);
392 // spilled_registers_ and spilled_double_registers_ are either 392 // spilled_registers_ and spilled_double_registers_ are either
393 // both NULL or both set. 393 // both NULL or both set.
394 if (environment->spilled_registers() != NULL && value != NULL) { 394 if (environment->spilled_registers() != NULL && value != NULL) {
395 if (value->IsRegister() && 395 if (value->IsRegister() &&
396 environment->spilled_registers()[value->index()] != NULL) { 396 environment->spilled_registers()[value->index()] != NULL) {
397 translation->MarkDuplicate(); 397 translation->MarkDuplicate();
398 AddToTranslation(translation, 398 AddToTranslation(translation,
399 environment->spilled_registers()[value->index()], 399 environment->spilled_registers()[value->index()],
400 environment->HasTaggedValueAt(i)); 400 environment->HasTaggedValueAt(i),
401 environment->HasUint32ValueAt(i));
401 } else if ( 402 } else if (
402 value->IsDoubleRegister() && 403 value->IsDoubleRegister() &&
403 environment->spilled_double_registers()[value->index()] != NULL) { 404 environment->spilled_double_registers()[value->index()] != NULL) {
404 translation->MarkDuplicate(); 405 translation->MarkDuplicate();
405 AddToTranslation( 406 AddToTranslation(
406 translation, 407 translation,
407 environment->spilled_double_registers()[value->index()], 408 environment->spilled_double_registers()[value->index()],
409 false,
408 false); 410 false);
409 } 411 }
410 } 412 }
411 413
412 AddToTranslation(translation, value, environment->HasTaggedValueAt(i)); 414 AddToTranslation(translation,
415 value,
416 environment->HasTaggedValueAt(i),
417 environment->HasUint32ValueAt(i));
413 } 418 }
414 } 419 }
415 420
416 421
417 void LCodeGen::AddToTranslation(Translation* translation, 422 void LCodeGen::AddToTranslation(Translation* translation,
418 LOperand* op, 423 LOperand* op,
419 bool is_tagged) { 424 bool is_tagged,
425 bool is_uint32) {
420 if (op == NULL) { 426 if (op == NULL) {
421 // TODO(twuerthinger): Introduce marker operands to indicate that this value 427 // TODO(twuerthinger): Introduce marker operands to indicate that this value
422 // is not present and must be reconstructed from the deoptimizer. Currently 428 // is not present and must be reconstructed from the deoptimizer. Currently
423 // this is only used for the arguments object. 429 // this is only used for the arguments object.
424 translation->StoreArgumentsObject(); 430 translation->StoreArgumentsObject();
425 } else if (op->IsStackSlot()) { 431 } else if (op->IsStackSlot()) {
426 if (is_tagged) { 432 if (is_tagged) {
427 translation->StoreStackSlot(op->index()); 433 translation->StoreStackSlot(op->index());
434 } else if (is_uint32) {
435 translation->StoreUint32StackSlot(op->index());
428 } else { 436 } else {
429 translation->StoreInt32StackSlot(op->index()); 437 translation->StoreInt32StackSlot(op->index());
430 } 438 }
431 } else if (op->IsDoubleStackSlot()) { 439 } else if (op->IsDoubleStackSlot()) {
432 translation->StoreDoubleStackSlot(op->index()); 440 translation->StoreDoubleStackSlot(op->index());
433 } else if (op->IsArgument()) { 441 } else if (op->IsArgument()) {
434 ASSERT(is_tagged); 442 ASSERT(is_tagged);
435 int src_index = GetStackSlotCount() + op->index(); 443 int src_index = GetStackSlotCount() + op->index();
436 translation->StoreStackSlot(src_index); 444 translation->StoreStackSlot(src_index);
437 } else if (op->IsRegister()) { 445 } else if (op->IsRegister()) {
438 Register reg = ToRegister(op); 446 Register reg = ToRegister(op);
439 if (is_tagged) { 447 if (is_tagged) {
440 translation->StoreRegister(reg); 448 translation->StoreRegister(reg);
449 } else if (is_uint32) {
450 translation->StoreUint32Register(reg);
441 } else { 451 } else {
442 translation->StoreInt32Register(reg); 452 translation->StoreInt32Register(reg);
443 } 453 }
444 } else if (op->IsDoubleRegister()) { 454 } else if (op->IsDoubleRegister()) {
445 XMMRegister reg = ToDoubleRegister(op); 455 XMMRegister reg = ToDoubleRegister(op);
446 translation->StoreDoubleRegister(reg); 456 translation->StoreDoubleRegister(reg);
447 } else if (op->IsConstantOperand()) { 457 } else if (op->IsConstantOperand()) {
448 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op)); 458 HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
449 int src_index = DefineDeoptimizationLiteral(constant->handle()); 459 int src_index = DefineDeoptimizationLiteral(constant->handle());
450 translation->StoreLiteral(src_index); 460 translation->StoreLiteral(src_index);
(...skipping 2264 matching lines...) Expand 10 before | Expand all | Expand 10 after
2715 __ movsxwq(result, operand); 2725 __ movsxwq(result, operand);
2716 break; 2726 break;
2717 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 2727 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
2718 __ movzxwq(result, operand); 2728 __ movzxwq(result, operand);
2719 break; 2729 break;
2720 case EXTERNAL_INT_ELEMENTS: 2730 case EXTERNAL_INT_ELEMENTS:
2721 __ movsxlq(result, operand); 2731 __ movsxlq(result, operand);
2722 break; 2732 break;
2723 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 2733 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
2724 __ movl(result, operand); 2734 __ movl(result, operand);
2725 __ testl(result, result); 2735 if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
2726 // TODO(danno): we could be more clever here, perhaps having a special 2736 __ testl(result, result);
2727 // version of the stub that detects if the overflow case actually 2737 DeoptimizeIf(negative, instr->environment());
2728 // happens, and generate code that returns a double rather than int. 2738 }
2729 DeoptimizeIf(negative, instr->environment());
2730 break; 2739 break;
2731 case EXTERNAL_FLOAT_ELEMENTS: 2740 case EXTERNAL_FLOAT_ELEMENTS:
2732 case EXTERNAL_DOUBLE_ELEMENTS: 2741 case EXTERNAL_DOUBLE_ELEMENTS:
2733 case FAST_ELEMENTS: 2742 case FAST_ELEMENTS:
2734 case FAST_SMI_ELEMENTS: 2743 case FAST_SMI_ELEMENTS:
2735 case FAST_DOUBLE_ELEMENTS: 2744 case FAST_DOUBLE_ELEMENTS:
2736 case FAST_HOLEY_ELEMENTS: 2745 case FAST_HOLEY_ELEMENTS:
2737 case FAST_HOLEY_SMI_ELEMENTS: 2746 case FAST_HOLEY_SMI_ELEMENTS:
2738 case FAST_HOLEY_DOUBLE_ELEMENTS: 2747 case FAST_HOLEY_DOUBLE_ELEMENTS:
2739 case DICTIONARY_ELEMENTS: 2748 case DICTIONARY_ELEMENTS:
(...skipping 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after
3982 LOperand* output = instr->result(); 3991 LOperand* output = instr->result();
3983 ASSERT(output->IsDoubleRegister()); 3992 ASSERT(output->IsDoubleRegister());
3984 if (input->IsRegister()) { 3993 if (input->IsRegister()) {
3985 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input)); 3994 __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input));
3986 } else { 3995 } else {
3987 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input)); 3996 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
3988 } 3997 }
3989 } 3998 }
3990 3999
3991 4000
4001 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4002 LOperand* input = instr->InputAt(0);
4003 LOperand* output = instr->result();
4004 LOperand* temp = instr->TempAt(0);
4005
4006 __ LoadUint32(ToDoubleRegister(output),
4007 ToRegister(input),
4008 ToDoubleRegister(temp));
4009 }
4010
4011
3992 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4012 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
3993 LOperand* input = instr->InputAt(0); 4013 LOperand* input = instr->InputAt(0);
3994 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4014 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3995 Register reg = ToRegister(input); 4015 Register reg = ToRegister(input);
3996 4016
3997 __ Integer32ToSmi(reg, reg); 4017 __ Integer32ToSmi(reg, reg);
3998 } 4018 }
3999 4019
4000 4020
4021 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4022 class DeferredNumberTagU: public LDeferredCode {
4023 public:
4024 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
4025 : LDeferredCode(codegen), instr_(instr) { }
4026 virtual void Generate() {
4027 codegen()->DoDeferredNumberTagU(instr_);
4028 }
4029 virtual LInstruction* instr() { return instr_; }
4030 private:
4031 LNumberTagU* instr_;
4032 };
4033
4034 LOperand* input = instr->InputAt(0);
4035 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4036 Register reg = ToRegister(input);
4037
4038 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4039 __ cmpl(reg, Immediate(Smi::kMaxValue));
4040 __ j(above, deferred->entry());
4041 __ Integer32ToSmi(reg, reg);
4042 __ bind(deferred->exit());
4043 }
4044
4045
4046 void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
4047 Label slow;
4048 Register reg = ToRegister(instr->InputAt(0));
4049 Register tmp = reg.is(rax) ? rcx : rax;
4050
4051 // Preserve the value of all registers.
4052 PushSafepointRegistersScope scope(this);
4053
4054 Label done;
4055 __ LoadUint32(xmm0, reg, xmm1);
4056
4057 if (FLAG_inline_new) {
4058 __ AllocateHeapNumber(reg, tmp, &slow);
4059 __ jmp(&done, Label::kNear);
4060 }
4061
4062 // Slow case: Call the runtime system to do the number allocation.
4063 __ bind(&slow);
4064
4065 // Put a valid pointer value in the stack slot where the result
4066 // register is stored, as this register is in the pointer map, but contains an
4067 // integer value.
4068 __ StoreToSafepointRegisterSlot(reg, Immediate(0));
4069
4070 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4071 if (!reg.is(rax)) __ movq(reg, rax);
4072
4073 // Done. Put the value in xmm0 into the value of the allocated heap
4074 // number.
4075 __ bind(&done);
4076 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
4077 __ StoreToSafepointRegisterSlot(reg, reg);
4078 }
4079
4080
4001 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4081 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4002 class DeferredNumberTagD: public LDeferredCode { 4082 class DeferredNumberTagD: public LDeferredCode {
4003 public: 4083 public:
4004 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4084 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4005 : LDeferredCode(codegen), instr_(instr) { } 4085 : LDeferredCode(codegen), instr_(instr) { }
4006 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4086 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4007 virtual LInstruction* instr() { return instr_; } 4087 virtual LInstruction* instr() { return instr_; }
4008 private: 4088 private:
4009 LNumberTagD* instr_; 4089 LNumberTagD* instr_;
4010 }; 4090 };
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after
5162 FixedArray::kHeaderSize - kPointerSize)); 5242 FixedArray::kHeaderSize - kPointerSize));
5163 __ bind(&done); 5243 __ bind(&done);
5164 } 5244 }
5165 5245
5166 5246
5167 #undef __ 5247 #undef __
5168 5248
5169 } } // namespace v8::internal 5249 } } // namespace v8::internal
5170 5250
5171 #endif // V8_TARGET_ARCH_X64 5251 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698