| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 1866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1877 int_value != 0 && | 1877 int_value != 0 && |
| 1878 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { | 1878 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { |
| 1879 operand->ToRegister(); | 1879 operand->ToRegister(); |
| 1880 frame_->Spill(operand->reg()); | 1880 frame_->Spill(operand->reg()); |
| 1881 DeferredCode* deferred = | 1881 DeferredCode* deferred = |
| 1882 new DeferredInlineSmiOperation(op, | 1882 new DeferredInlineSmiOperation(op, |
| 1883 operand->reg(), | 1883 operand->reg(), |
| 1884 operand->reg(), | 1884 operand->reg(), |
| 1885 smi_value, | 1885 smi_value, |
| 1886 overwrite_mode); | 1886 overwrite_mode); |
| 1887 // Check for negative or non-Smi left hand side. | 1887 __ JumpUnlessNonNegativeSmi(operand->reg(), deferred->entry_label()); |
| 1888 __ JumpIfNotPositiveSmi(operand->reg(), deferred->entry_label()); | |
| 1889 if (int_value < 0) int_value = -int_value; | 1888 if (int_value < 0) int_value = -int_value; |
| 1890 if (int_value == 1) { | 1889 if (int_value == 1) { |
| 1891 __ Move(operand->reg(), Smi::FromInt(0)); | 1890 __ Move(operand->reg(), Smi::FromInt(0)); |
| 1892 } else { | 1891 } else { |
| 1893 __ SmiAndConstant(operand->reg(), | 1892 __ SmiAndConstant(operand->reg(), |
| 1894 operand->reg(), | 1893 operand->reg(), |
| 1895 Smi::FromInt(int_value - 1)); | 1894 Smi::FromInt(int_value - 1)); |
| 1896 } | 1895 } |
| 1897 deferred->BindExit(); | 1896 deferred->BindExit(); |
| 1898 answer = *operand; | 1897 answer = *operand; |
| (...skipping 3778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5677 frame_->Push(Factory::undefined_value()); | 5676 frame_->Push(Factory::undefined_value()); |
| 5678 } | 5677 } |
| 5679 | 5678 |
| 5680 | 5679 |
| 5681 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { | 5680 void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) { |
| 5682 ASSERT(args->length() == 1); | 5681 ASSERT(args->length() == 1); |
| 5683 Load(args->at(0)); | 5682 Load(args->at(0)); |
| 5684 Result value = frame_->Pop(); | 5683 Result value = frame_->Pop(); |
| 5685 value.ToRegister(); | 5684 value.ToRegister(); |
| 5686 ASSERT(value.is_valid()); | 5685 ASSERT(value.is_valid()); |
| 5687 Condition positive_smi = masm_->CheckPositiveSmi(value.reg()); | 5686 Condition non_negative_smi = masm_->CheckNonNegativeSmi(value.reg()); |
| 5688 value.Unuse(); | 5687 value.Unuse(); |
| 5689 destination()->Split(positive_smi); | 5688 destination()->Split(non_negative_smi); |
| 5690 } | 5689 } |
| 5691 | 5690 |
| 5692 | 5691 |
| 5693 class DeferredStringCharCodeAt : public DeferredCode { | 5692 class DeferredStringCharCodeAt : public DeferredCode { |
| 5694 public: | 5693 public: |
| 5695 DeferredStringCharCodeAt(Register object, | 5694 DeferredStringCharCodeAt(Register object, |
| 5696 Register index, | 5695 Register index, |
| 5697 Register scratch, | 5696 Register scratch, |
| 5698 Register result) | 5697 Register result) |
| 5699 : result_(result), | 5698 : result_(result), |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6904 Immediate(KeyedLoadIC::kSlowCaseBitFieldMask)); | 6903 Immediate(KeyedLoadIC::kSlowCaseBitFieldMask)); |
| 6905 deferred->Branch(not_zero); | 6904 deferred->Branch(not_zero); |
| 6906 | 6905 |
| 6907 // Check the object's elements are in fast case and writable. | 6906 // Check the object's elements are in fast case and writable. |
| 6908 __ movq(tmp1.reg(), FieldOperand(object.reg(), JSObject::kElementsOffset)); | 6907 __ movq(tmp1.reg(), FieldOperand(object.reg(), JSObject::kElementsOffset)); |
| 6909 __ CompareRoot(FieldOperand(tmp1.reg(), HeapObject::kMapOffset), | 6908 __ CompareRoot(FieldOperand(tmp1.reg(), HeapObject::kMapOffset), |
| 6910 Heap::kFixedArrayMapRootIndex); | 6909 Heap::kFixedArrayMapRootIndex); |
| 6911 deferred->Branch(not_equal); | 6910 deferred->Branch(not_equal); |
| 6912 | 6911 |
| 6913 // Check that both indices are smis. | 6912 // Check that both indices are smis. |
| 6914 Condition both_smi = __ CheckBothSmi(index1.reg(), index2.reg()); | 6913 Condition both_smi = masm()->CheckBothSmi(index1.reg(), index2.reg()); |
| 6915 deferred->Branch(NegateCondition(both_smi)); | 6914 deferred->Branch(NegateCondition(both_smi)); |
| 6916 | 6915 |
| 6917 // Bring addresses into index1 and index2. | 6916 // Bring addresses into index1 and index2. |
| 6918 __ SmiToInteger32(index1.reg(), index1.reg()); | 6917 __ SmiToInteger32(index1.reg(), index1.reg()); |
| 6919 __ lea(index1.reg(), FieldOperand(tmp1.reg(), | 6918 __ lea(index1.reg(), FieldOperand(tmp1.reg(), |
| 6920 index1.reg(), | 6919 index1.reg(), |
| 6921 times_pointer_size, | 6920 times_pointer_size, |
| 6922 FixedArray::kHeaderSize)); | 6921 FixedArray::kHeaderSize)); |
| 6923 __ SmiToInteger32(index2.reg(), index2.reg()); | 6922 __ SmiToInteger32(index2.reg(), index2.reg()); |
| 6924 __ lea(index2.reg(), FieldOperand(tmp1.reg(), | 6923 __ lea(index2.reg(), FieldOperand(tmp1.reg(), |
| (...skipping 1445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8370 if (receiver.reg().is(r12)) { | 8369 if (receiver.reg().is(r12)) { |
| 8371 frame()->Spill(receiver.reg()); // It will be overwritten with result. | 8370 frame()->Spill(receiver.reg()); // It will be overwritten with result. |
| 8372 // Swap receiver and value. | 8371 // Swap receiver and value. |
| 8373 __ movq(result.reg(), receiver.reg()); | 8372 __ movq(result.reg(), receiver.reg()); |
| 8374 Result temp = receiver; | 8373 Result temp = receiver; |
| 8375 receiver = result; | 8374 receiver = result; |
| 8376 result = temp; | 8375 result = temp; |
| 8377 } | 8376 } |
| 8378 | 8377 |
| 8379 // Check that the receiver is a heap object. | 8378 // Check that the receiver is a heap object. |
| 8380 Condition is_smi = __ CheckSmi(receiver.reg()); | 8379 Condition is_smi = masm()->CheckSmi(receiver.reg()); |
| 8381 slow.Branch(is_smi, &value, &receiver); | 8380 slow.Branch(is_smi, &value, &receiver); |
| 8382 | 8381 |
| 8383 // This is the map check instruction that will be patched. | 8382 // This is the map check instruction that will be patched. |
| 8384 // Initially use an invalid map to force a failure. The exact | 8383 // Initially use an invalid map to force a failure. The exact |
| 8385 // instruction sequence is important because we use the | 8384 // instruction sequence is important because we use the |
| 8386 // kOffsetToStoreInstruction constant for patching. We avoid using | 8385 // kOffsetToStoreInstruction constant for patching. We avoid using |
| 8387 // the __ macro for the following two instructions because it | 8386 // the __ macro for the following two instructions because it |
| 8388 // might introduce extra instructions. | 8387 // might introduce extra instructions. |
| 8389 __ bind(&patch_site); | 8388 __ bind(&patch_site); |
| 8390 masm()->Move(kScratchRegister, Factory::null_value()); | 8389 masm()->Move(kScratchRegister, Factory::null_value()); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8499 // Use masm-> here instead of the double underscore macro since extra | 8498 // Use masm-> here instead of the double underscore macro since extra |
| 8500 // coverage code can interfere with the patching. Do not use a load | 8499 // coverage code can interfere with the patching. Do not use a load |
| 8501 // from the root array to load null_value, since the load must be patched | 8500 // from the root array to load null_value, since the load must be patched |
| 8502 // with the expected receiver map, which is not in the root array. | 8501 // with the expected receiver map, which is not in the root array. |
| 8503 masm_->movq(kScratchRegister, Factory::null_value(), | 8502 masm_->movq(kScratchRegister, Factory::null_value(), |
| 8504 RelocInfo::EMBEDDED_OBJECT); | 8503 RelocInfo::EMBEDDED_OBJECT); |
| 8505 masm_->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset), | 8504 masm_->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset), |
| 8506 kScratchRegister); | 8505 kScratchRegister); |
| 8507 deferred->Branch(not_equal); | 8506 deferred->Branch(not_equal); |
| 8508 | 8507 |
| 8509 // Check that the key is a non-negative smi. | 8508 __ JumpUnlessNonNegativeSmi(key.reg(), deferred->entry_label()); |
| 8510 __ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label()); | |
| 8511 | 8509 |
| 8512 // Get the elements array from the receiver. | 8510 // Get the elements array from the receiver. |
| 8513 __ movq(elements.reg(), | 8511 __ movq(elements.reg(), |
| 8514 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 8512 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
| 8515 __ AssertFastElements(elements.reg()); | 8513 __ AssertFastElements(elements.reg()); |
| 8516 | 8514 |
| 8517 // Check that key is within bounds. | 8515 // Check that key is within bounds. |
| 8518 __ SmiCompare(key.reg(), | 8516 __ SmiCompare(key.reg(), |
| 8519 FieldOperand(elements.reg(), FixedArray::kLengthOffset)); | 8517 FieldOperand(elements.reg(), FixedArray::kLengthOffset)); |
| 8520 deferred->Branch(above_equal); | 8518 deferred->Branch(above_equal); |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8925 #undef __ | 8923 #undef __ |
| 8926 | 8924 |
| 8927 void RecordWriteStub::Generate(MacroAssembler* masm) { | 8925 void RecordWriteStub::Generate(MacroAssembler* masm) { |
| 8928 masm->RecordWriteHelper(object_, addr_, scratch_); | 8926 masm->RecordWriteHelper(object_, addr_, scratch_); |
| 8929 masm->ret(0); | 8927 masm->ret(0); |
| 8930 } | 8928 } |
| 8931 | 8929 |
| 8932 } } // namespace v8::internal | 8930 } } // namespace v8::internal |
| 8933 | 8931 |
| 8934 #endif // V8_TARGET_ARCH_X64 | 8932 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |