| OLD | NEW |
| 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 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 } | 678 } |
| 679 | 679 |
| 680 | 680 |
| 681 double LCodeGen::ToDouble(LConstantOperand* op) const { | 681 double LCodeGen::ToDouble(LConstantOperand* op) const { |
| 682 HConstant* constant = chunk_->LookupConstant(op); | 682 HConstant* constant = chunk_->LookupConstant(op); |
| 683 ASSERT(constant->HasDoubleValue()); | 683 ASSERT(constant->HasDoubleValue()); |
| 684 return constant->DoubleValue(); | 684 return constant->DoubleValue(); |
| 685 } | 685 } |
| 686 | 686 |
| 687 | 687 |
| 688 ExternalReference LCodeGen::ToExternalReference(LConstantOperand* op) const { | |
| 689 HConstant* constant = chunk_->LookupConstant(op); | |
| 690 ASSERT(constant->HasExternalReferenceValue()); | |
| 691 return constant->ExternalReferenceValue(); | |
| 692 } | |
| 693 | |
| 694 | |
| 695 bool LCodeGen::IsInteger32(LConstantOperand* op) const { | 688 bool LCodeGen::IsInteger32(LConstantOperand* op) const { |
| 696 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); | 689 return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); |
| 697 } | 690 } |
| 698 | 691 |
| 699 | 692 |
| 700 bool LCodeGen::IsSmi(LConstantOperand* op) const { | 693 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
| 701 return chunk_->LookupLiteralRepresentation(op).IsSmi(); | 694 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
| 702 } | 695 } |
| 703 | 696 |
| 704 | 697 |
| (...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 case Token::SHR: | 1755 case Token::SHR: |
| 1763 if (shift_count == 0 && instr->can_deopt()) { | 1756 if (shift_count == 0 && instr->can_deopt()) { |
| 1764 __ test(ToRegister(left), Immediate(0x80000000)); | 1757 __ test(ToRegister(left), Immediate(0x80000000)); |
| 1765 DeoptimizeIf(not_zero, instr->environment()); | 1758 DeoptimizeIf(not_zero, instr->environment()); |
| 1766 } else { | 1759 } else { |
| 1767 __ shr(ToRegister(left), shift_count); | 1760 __ shr(ToRegister(left), shift_count); |
| 1768 } | 1761 } |
| 1769 break; | 1762 break; |
| 1770 case Token::SHL: | 1763 case Token::SHL: |
| 1771 if (shift_count != 0) { | 1764 if (shift_count != 0) { |
| 1772 if (instr->hydrogen_value()->representation().IsSmi() && | 1765 __ shl(ToRegister(left), shift_count); |
| 1773 instr->can_deopt()) { | |
| 1774 __ shl(ToRegister(left), shift_count - 1); | |
| 1775 __ SmiTag(ToRegister(left)); | |
| 1776 DeoptimizeIf(overflow, instr->environment()); | |
| 1777 } else { | |
| 1778 __ shl(ToRegister(left), shift_count); | |
| 1779 } | |
| 1780 } | 1766 } |
| 1781 break; | 1767 break; |
| 1782 default: | 1768 default: |
| 1783 UNREACHABLE(); | 1769 UNREACHABLE(); |
| 1784 break; | 1770 break; |
| 1785 } | 1771 } |
| 1786 } | 1772 } |
| 1787 } | 1773 } |
| 1788 | 1774 |
| 1789 | 1775 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 __ Set(temp, Immediate(lower)); | 1839 __ Set(temp, Immediate(lower)); |
| 1854 __ movd(xmm0, Operand(temp)); | 1840 __ movd(xmm0, Operand(temp)); |
| 1855 __ por(res, xmm0); | 1841 __ por(res, xmm0); |
| 1856 } | 1842 } |
| 1857 } | 1843 } |
| 1858 } | 1844 } |
| 1859 } | 1845 } |
| 1860 } | 1846 } |
| 1861 | 1847 |
| 1862 | 1848 |
| 1863 void LCodeGen::DoConstantE(LConstantE* instr) { | |
| 1864 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); | |
| 1865 } | |
| 1866 | |
| 1867 | |
| 1868 void LCodeGen::DoConstantT(LConstantT* instr) { | 1849 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1869 Register reg = ToRegister(instr->result()); | 1850 Register reg = ToRegister(instr->result()); |
| 1870 Handle<Object> handle = instr->value(); | 1851 Handle<Object> handle = instr->value(); |
| 1871 AllowDeferredHandleDereference smi_check; | 1852 AllowDeferredHandleDereference smi_check; |
| 1872 __ LoadObject(reg, handle); | 1853 __ LoadObject(reg, handle); |
| 1873 } | 1854 } |
| 1874 | 1855 |
| 1875 | 1856 |
| 1876 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { | 1857 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { |
| 1877 Register result = ToRegister(instr->result()); | 1858 Register result = ToRegister(instr->result()); |
| (...skipping 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3054 check_needed); | 3035 check_needed); |
| 3055 } | 3036 } |
| 3056 | 3037 |
| 3057 __ bind(&skip_assignment); | 3038 __ bind(&skip_assignment); |
| 3058 } | 3039 } |
| 3059 | 3040 |
| 3060 | 3041 |
| 3061 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 3042 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
| 3062 HObjectAccess access = instr->hydrogen()->access(); | 3043 HObjectAccess access = instr->hydrogen()->access(); |
| 3063 int offset = access.offset(); | 3044 int offset = access.offset(); |
| 3064 | |
| 3065 if (access.IsExternalMemory()) { | |
| 3066 Register result = ToRegister(instr->result()); | |
| 3067 if (instr->object()->IsConstantOperand()) { | |
| 3068 ExternalReference external_reference = ToExternalReference( | |
| 3069 LConstantOperand::cast(instr->object())); | |
| 3070 __ mov(result, MemOperand::StaticVariable(external_reference)); | |
| 3071 } else { | |
| 3072 __ mov(result, MemOperand(ToRegister(instr->object()), offset)); | |
| 3073 } | |
| 3074 return; | |
| 3075 } | |
| 3076 | |
| 3077 Register object = ToRegister(instr->object()); | 3045 Register object = ToRegister(instr->object()); |
| 3078 if (FLAG_track_double_fields && | 3046 if (FLAG_track_double_fields && |
| 3079 instr->hydrogen()->representation().IsDouble()) { | 3047 instr->hydrogen()->representation().IsDouble()) { |
| 3080 if (CpuFeatures::IsSupported(SSE2)) { | 3048 if (CpuFeatures::IsSupported(SSE2)) { |
| 3081 CpuFeatureScope scope(masm(), SSE2); | 3049 CpuFeatureScope scope(masm(), SSE2); |
| 3082 XMMRegister result = ToDoubleRegister(instr->result()); | 3050 XMMRegister result = ToDoubleRegister(instr->result()); |
| 3083 __ movdbl(result, FieldOperand(object, offset)); | 3051 __ movdbl(result, FieldOperand(object, offset)); |
| 3084 } else { | 3052 } else { |
| 3085 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); | 3053 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); |
| 3086 } | 3054 } |
| (...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4346 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 4314 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
| 4347 Register result = ToRegister(instr->result()); | 4315 Register result = ToRegister(instr->result()); |
| 4348 Register base = ToRegister(instr->base_object()); | 4316 Register base = ToRegister(instr->base_object()); |
| 4349 __ lea(result, Operand(base, instr->offset())); | 4317 __ lea(result, Operand(base, instr->offset())); |
| 4350 } | 4318 } |
| 4351 | 4319 |
| 4352 | 4320 |
| 4353 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 4321 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 4354 Representation representation = instr->representation(); | 4322 Representation representation = instr->representation(); |
| 4355 | 4323 |
| 4324 Register object = ToRegister(instr->object()); |
| 4356 HObjectAccess access = instr->hydrogen()->access(); | 4325 HObjectAccess access = instr->hydrogen()->access(); |
| 4357 int offset = access.offset(); | 4326 int offset = access.offset(); |
| 4358 | 4327 |
| 4359 if (access.IsExternalMemory()) { | |
| 4360 MemOperand operand = instr->object()->IsConstantOperand() | |
| 4361 ? MemOperand::StaticVariable( | |
| 4362 ToExternalReference(LConstantOperand::cast(instr->object()))) | |
| 4363 : MemOperand(ToRegister(instr->object()), offset); | |
| 4364 if (instr->value()->IsConstantOperand()) { | |
| 4365 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | |
| 4366 __ mov(operand, Immediate(ToInteger32(operand_value))); | |
| 4367 } else { | |
| 4368 Register value = ToRegister(instr->value()); | |
| 4369 __ mov(operand, value); | |
| 4370 } | |
| 4371 return; | |
| 4372 } | |
| 4373 | |
| 4374 Register object = ToRegister(instr->object()); | |
| 4375 Handle<Map> transition = instr->transition(); | 4328 Handle<Map> transition = instr->transition(); |
| 4376 | 4329 |
| 4377 if (FLAG_track_fields && representation.IsSmi()) { | 4330 if (FLAG_track_fields && representation.IsSmi()) { |
| 4378 if (instr->value()->IsConstantOperand()) { | 4331 if (instr->value()->IsConstantOperand()) { |
| 4379 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4332 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4380 if (!IsSmi(operand_value)) { | 4333 if (!IsSmi(operand_value)) { |
| 4381 DeoptimizeIf(no_condition, instr->environment()); | 4334 DeoptimizeIf(no_condition, instr->environment()); |
| 4382 } | 4335 } |
| 4383 } | 4336 } |
| 4384 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 4337 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4429 } | 4382 } |
| 4430 | 4383 |
| 4431 // Do the store. | 4384 // Do the store. |
| 4432 SmiCheck check_needed = | 4385 SmiCheck check_needed = |
| 4433 instr->hydrogen()->value()->IsHeapObject() | 4386 instr->hydrogen()->value()->IsHeapObject() |
| 4434 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4387 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4435 | 4388 |
| 4436 Register write_register = object; | 4389 Register write_register = object; |
| 4437 if (!access.IsInobject()) { | 4390 if (!access.IsInobject()) { |
| 4438 write_register = ToRegister(instr->temp()); | 4391 write_register = ToRegister(instr->temp()); |
| 4439 __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); | 4392 __ mov(write_register, |
| 4393 FieldOperand(object, JSObject::kPropertiesOffset)); |
| 4440 } | 4394 } |
| 4441 | 4395 |
| 4442 if (instr->value()->IsConstantOperand()) { | 4396 if (instr->value()->IsConstantOperand()) { |
| 4443 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4397 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4444 if (operand_value->IsRegister()) { | 4398 if (operand_value->IsRegister()) { |
| 4445 __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); | 4399 __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); |
| 4446 } else { | 4400 } else { |
| 4447 Handle<Object> handle_value = ToHandle(operand_value); | 4401 Handle<Object> handle_value = ToHandle(operand_value); |
| 4448 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4402 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 4449 __ mov(FieldOperand(write_register, offset), handle_value); | 4403 __ mov(FieldOperand(write_register, offset), handle_value); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4747 if (is_simple_map_transition) { | 4701 if (is_simple_map_transition) { |
| 4748 Register new_map_reg = ToRegister(instr->new_map_temp()); | 4702 Register new_map_reg = ToRegister(instr->new_map_temp()); |
| 4749 Handle<Map> map = instr->hydrogen()->transitioned_map(); | 4703 Handle<Map> map = instr->hydrogen()->transitioned_map(); |
| 4750 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), | 4704 __ mov(FieldOperand(object_reg, HeapObject::kMapOffset), |
| 4751 Immediate(map)); | 4705 Immediate(map)); |
| 4752 // Write barrier. | 4706 // Write barrier. |
| 4753 ASSERT_NE(instr->temp(), NULL); | 4707 ASSERT_NE(instr->temp(), NULL); |
| 4754 __ RecordWriteForMap(object_reg, to_map, new_map_reg, | 4708 __ RecordWriteForMap(object_reg, to_map, new_map_reg, |
| 4755 ToRegister(instr->temp()), | 4709 ToRegister(instr->temp()), |
| 4756 kDontSaveFPRegs); | 4710 kDontSaveFPRegs); |
| 4757 } else { | 4711 } else if (FLAG_compiled_transitions) { |
| 4758 PushSafepointRegistersScope scope(this); | 4712 PushSafepointRegistersScope scope(this); |
| 4759 if (!object_reg.is(eax)) { | 4713 if (!object_reg.is(eax)) { |
| 4760 __ push(object_reg); | 4714 __ push(object_reg); |
| 4761 } | 4715 } |
| 4762 LoadContextFromDeferred(instr->context()); | 4716 LoadContextFromDeferred(instr->context()); |
| 4763 if (!object_reg.is(eax)) { | 4717 if (!object_reg.is(eax)) { |
| 4764 __ pop(eax); | 4718 __ pop(eax); |
| 4765 } | 4719 } |
| 4766 __ mov(ebx, to_map); | 4720 __ mov(ebx, to_map); |
| 4767 TransitionElementsKindStub stub(from_kind, to_kind); | 4721 TransitionElementsKindStub stub(from_kind, to_kind); |
| 4768 __ CallStub(&stub); | 4722 __ CallStub(&stub); |
| 4769 RecordSafepointWithRegisters( | 4723 RecordSafepointWithRegisters( |
| 4770 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4724 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4725 } else if (IsFastSmiElementsKind(from_kind) && |
| 4726 IsFastDoubleElementsKind(to_kind)) { |
| 4727 Register new_map_reg = ToRegister(instr->new_map_temp()); |
| 4728 __ mov(new_map_reg, to_map); |
| 4729 Register fixed_object_reg = ToRegister(instr->temp()); |
| 4730 ASSERT(fixed_object_reg.is(edx)); |
| 4731 ASSERT(new_map_reg.is(ebx)); |
| 4732 __ mov(fixed_object_reg, object_reg); |
| 4733 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), |
| 4734 RelocInfo::CODE_TARGET, instr); |
| 4735 } else if (IsFastDoubleElementsKind(from_kind) && |
| 4736 IsFastObjectElementsKind(to_kind)) { |
| 4737 Register new_map_reg = ToRegister(instr->new_map_temp()); |
| 4738 __ mov(new_map_reg, to_map); |
| 4739 Register fixed_object_reg = ToRegister(instr->temp()); |
| 4740 ASSERT(fixed_object_reg.is(edx)); |
| 4741 ASSERT(new_map_reg.is(ebx)); |
| 4742 __ mov(fixed_object_reg, object_reg); |
| 4743 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), |
| 4744 RelocInfo::CODE_TARGET, instr); |
| 4745 } else { |
| 4746 UNREACHABLE(); |
| 4771 } | 4747 } |
| 4772 __ bind(¬_applicable); | 4748 __ bind(¬_applicable); |
| 4773 } | 4749 } |
| 4774 | 4750 |
| 4775 | 4751 |
| 4776 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4752 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 4777 class DeferredStringCharCodeAt: public LDeferredCode { | 4753 class DeferredStringCharCodeAt: public LDeferredCode { |
| 4778 public: | 4754 public: |
| 4779 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4755 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| 4780 : LDeferredCode(codegen), instr_(instr) { } | 4756 : LDeferredCode(codegen), instr_(instr) { } |
| (...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6523 FixedArray::kHeaderSize - kPointerSize)); | 6499 FixedArray::kHeaderSize - kPointerSize)); |
| 6524 __ bind(&done); | 6500 __ bind(&done); |
| 6525 } | 6501 } |
| 6526 | 6502 |
| 6527 | 6503 |
| 6528 #undef __ | 6504 #undef __ |
| 6529 | 6505 |
| 6530 } } // namespace v8::internal | 6506 } } // namespace v8::internal |
| 6531 | 6507 |
| 6532 #endif // V8_TARGET_ARCH_IA32 | 6508 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |