| 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 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 #include "mips/lithium-codegen-mips.h" | 30 #include "mips/lithium-codegen-mips.h" |
| 31 #include "mips/lithium-gap-resolver-mips.h" | 31 #include "mips/lithium-gap-resolver-mips.h" |
| 32 #include "code-stubs.h" | 32 #include "code-stubs.h" |
| 33 #include "stub-cache.h" | 33 #include "stub-cache.h" |
| 34 | 34 |
| 35 namespace v8 { | 35 namespace v8 { |
| 36 namespace internal { | 36 namespace internal { |
| 37 | 37 |
| 38 | 38 |
| 39 static SaveFPRegsMode GetSaveFPRegsMode() { |
| 40 // We don't need to save floating point regs when generating the snapshot |
| 41 return CpuFeatures::IsSafeForSnapshot(FPU) |
| 42 ? kSaveFPRegs |
| 43 : kDontSaveFPRegs; |
| 44 } |
| 45 |
| 46 |
| 39 class SafepointGenerator : public CallWrapper { | 47 class SafepointGenerator : public CallWrapper { |
| 40 public: | 48 public: |
| 41 SafepointGenerator(LCodeGen* codegen, | 49 SafepointGenerator(LCodeGen* codegen, |
| 42 LPointerMap* pointers, | 50 LPointerMap* pointers, |
| 43 Safepoint::DeoptMode mode) | 51 Safepoint::DeoptMode mode) |
| 44 : codegen_(codegen), | 52 : codegen_(codegen), |
| 45 pointers_(pointers), | 53 pointers_(pointers), |
| 46 deopt_mode_(mode) { } | 54 deopt_mode_(mode) { } |
| 47 virtual ~SafepointGenerator() { } | 55 virtual ~SafepointGenerator() { } |
| 48 | 56 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 if (var->IsContextSlot()) { | 236 if (var->IsContextSlot()) { |
| 229 int parameter_offset = StandardFrameConstants::kCallerSPOffset + | 237 int parameter_offset = StandardFrameConstants::kCallerSPOffset + |
| 230 (num_parameters - 1 - i) * kPointerSize; | 238 (num_parameters - 1 - i) * kPointerSize; |
| 231 // Load parameter from stack. | 239 // Load parameter from stack. |
| 232 __ lw(a0, MemOperand(fp, parameter_offset)); | 240 __ lw(a0, MemOperand(fp, parameter_offset)); |
| 233 // Store it in the context. | 241 // Store it in the context. |
| 234 MemOperand target = ContextOperand(cp, var->index()); | 242 MemOperand target = ContextOperand(cp, var->index()); |
| 235 __ sw(a0, target); | 243 __ sw(a0, target); |
| 236 // Update the write barrier. This clobbers a3 and a0. | 244 // Update the write barrier. This clobbers a3 and a0. |
| 237 __ RecordWriteContextSlot( | 245 __ RecordWriteContextSlot( |
| 238 cp, target.offset(), a0, a3, GetRAState(), kSaveFPRegs); | 246 cp, |
| 247 target.offset(), |
| 248 a0, |
| 249 a3, |
| 250 GetRAState(), |
| 251 GetSaveFPRegsMode()); |
| 239 } | 252 } |
| 240 } | 253 } |
| 241 Comment(";;; End allocate local context"); | 254 Comment(";;; End allocate local context"); |
| 242 } | 255 } |
| 243 | 256 |
| 244 // Trace the call. | 257 // Trace the call. |
| 245 if (FLAG_trace && info()->IsOptimizing()) { | 258 if (FLAG_trace && info()->IsOptimizing()) { |
| 246 __ CallRuntime(Runtime::kTraceEnter, 0); | 259 __ CallRuntime(Runtime::kTraceEnter, 0); |
| 247 } | 260 } |
| 248 EnsureSpaceForLazyDeopt(); | 261 EnsureSpaceForLazyDeopt(); |
| (...skipping 2423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2672 __ sw(value, target); | 2685 __ sw(value, target); |
| 2673 if (instr->hydrogen()->NeedsWriteBarrier()) { | 2686 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 2674 HType type = instr->hydrogen()->value()->type(); | 2687 HType type = instr->hydrogen()->value()->type(); |
| 2675 SmiCheck check_needed = | 2688 SmiCheck check_needed = |
| 2676 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 2689 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 2677 __ RecordWriteContextSlot(context, | 2690 __ RecordWriteContextSlot(context, |
| 2678 target.offset(), | 2691 target.offset(), |
| 2679 value, | 2692 value, |
| 2680 scratch0(), | 2693 scratch0(), |
| 2681 GetRAState(), | 2694 GetRAState(), |
| 2682 kSaveFPRegs, | 2695 GetSaveFPRegsMode(), |
| 2683 EMIT_REMEMBERED_SET, | 2696 EMIT_REMEMBERED_SET, |
| 2684 check_needed); | 2697 check_needed); |
| 2685 } | 2698 } |
| 2686 | 2699 |
| 2687 __ bind(&skip_assignment); | 2700 __ bind(&skip_assignment); |
| 2688 } | 2701 } |
| 2689 | 2702 |
| 2690 | 2703 |
| 2691 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2704 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
| 2692 Register object = ToRegister(instr->object()); | 2705 Register object = ToRegister(instr->object()); |
| (...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3910 __ li(scratch, Operand(instr->transition())); | 3923 __ li(scratch, Operand(instr->transition())); |
| 3911 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); | 3924 __ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
| 3912 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { | 3925 if (instr->hydrogen()->NeedsWriteBarrierForMap()) { |
| 3913 Register temp = ToRegister(instr->temp()); | 3926 Register temp = ToRegister(instr->temp()); |
| 3914 // Update the write barrier for the map field. | 3927 // Update the write barrier for the map field. |
| 3915 __ RecordWriteField(object, | 3928 __ RecordWriteField(object, |
| 3916 HeapObject::kMapOffset, | 3929 HeapObject::kMapOffset, |
| 3917 scratch, | 3930 scratch, |
| 3918 temp, | 3931 temp, |
| 3919 GetRAState(), | 3932 GetRAState(), |
| 3920 kSaveFPRegs, | 3933 GetSaveFPRegsMode(), |
| 3921 OMIT_REMEMBERED_SET, | 3934 OMIT_REMEMBERED_SET, |
| 3922 OMIT_SMI_CHECK); | 3935 OMIT_SMI_CHECK); |
| 3923 } | 3936 } |
| 3924 } | 3937 } |
| 3925 | 3938 |
| 3926 // Do the store. | 3939 // Do the store. |
| 3927 HType type = instr->hydrogen()->value()->type(); | 3940 HType type = instr->hydrogen()->value()->type(); |
| 3928 SmiCheck check_needed = | 3941 SmiCheck check_needed = |
| 3929 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 3942 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 3930 if (instr->is_in_object()) { | 3943 if (instr->is_in_object()) { |
| 3931 __ sw(value, FieldMemOperand(object, offset)); | 3944 __ sw(value, FieldMemOperand(object, offset)); |
| 3932 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3945 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3933 // Update the write barrier for the object for in-object properties. | 3946 // Update the write barrier for the object for in-object properties. |
| 3934 __ RecordWriteField(object, | 3947 __ RecordWriteField(object, |
| 3935 offset, | 3948 offset, |
| 3936 value, | 3949 value, |
| 3937 scratch, | 3950 scratch, |
| 3938 GetRAState(), | 3951 GetRAState(), |
| 3939 kSaveFPRegs, | 3952 GetSaveFPRegsMode(), |
| 3940 EMIT_REMEMBERED_SET, | 3953 EMIT_REMEMBERED_SET, |
| 3941 check_needed); | 3954 check_needed); |
| 3942 } | 3955 } |
| 3943 } else { | 3956 } else { |
| 3944 __ lw(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 3957 __ lw(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 3945 __ sw(value, FieldMemOperand(scratch, offset)); | 3958 __ sw(value, FieldMemOperand(scratch, offset)); |
| 3946 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3959 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 3947 // Update the write barrier for the properties array. | 3960 // Update the write barrier for the properties array. |
| 3948 // object is used as a scratch register. | 3961 // object is used as a scratch register. |
| 3949 __ RecordWriteField(scratch, | 3962 __ RecordWriteField(scratch, |
| 3950 offset, | 3963 offset, |
| 3951 value, | 3964 value, |
| 3952 object, | 3965 object, |
| 3953 GetRAState(), | 3966 GetRAState(), |
| 3954 kSaveFPRegs, | 3967 GetSaveFPRegsMode(), |
| 3955 EMIT_REMEMBERED_SET, | 3968 EMIT_REMEMBERED_SET, |
| 3956 check_needed); | 3969 check_needed); |
| 3957 } | 3970 } |
| 3958 } | 3971 } |
| 3959 } | 3972 } |
| 3960 | 3973 |
| 3961 | 3974 |
| 3962 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 3975 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
| 3963 ASSERT(ToRegister(instr->object()).is(a1)); | 3976 ASSERT(ToRegister(instr->object()).is(a1)); |
| 3964 ASSERT(ToRegister(instr->value()).is(a0)); | 3977 ASSERT(ToRegister(instr->value()).is(a0)); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4153 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4166 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4154 HType type = instr->hydrogen()->value()->type(); | 4167 HType type = instr->hydrogen()->value()->type(); |
| 4155 SmiCheck check_needed = | 4168 SmiCheck check_needed = |
| 4156 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4169 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4157 // Compute address of modified element and store it into key register. | 4170 // Compute address of modified element and store it into key register. |
| 4158 __ Addu(key, store_base, Operand(offset - kHeapObjectTag)); | 4171 __ Addu(key, store_base, Operand(offset - kHeapObjectTag)); |
| 4159 __ RecordWrite(elements, | 4172 __ RecordWrite(elements, |
| 4160 key, | 4173 key, |
| 4161 value, | 4174 value, |
| 4162 GetRAState(), | 4175 GetRAState(), |
| 4163 kSaveFPRegs, | 4176 GetSaveFPRegsMode(), |
| 4164 EMIT_REMEMBERED_SET, | 4177 EMIT_REMEMBERED_SET, |
| 4165 check_needed); | 4178 check_needed); |
| 4166 } | 4179 } |
| 4167 } | 4180 } |
| 4168 | 4181 |
| 4169 | 4182 |
| 4170 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4183 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
| 4171 // By cases: external, fast double | 4184 // By cases: external, fast double |
| 4172 if (instr->is_external()) { | 4185 if (instr->is_external()) { |
| 4173 DoStoreKeyedExternalArray(instr); | 4186 DoStoreKeyedExternalArray(instr); |
| (...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5720 __ Subu(scratch, result, scratch); | 5733 __ Subu(scratch, result, scratch); |
| 5721 __ lw(result, FieldMemOperand(scratch, | 5734 __ lw(result, FieldMemOperand(scratch, |
| 5722 FixedArray::kHeaderSize - kPointerSize)); | 5735 FixedArray::kHeaderSize - kPointerSize)); |
| 5723 __ bind(&done); | 5736 __ bind(&done); |
| 5724 } | 5737 } |
| 5725 | 5738 |
| 5726 | 5739 |
| 5727 #undef __ | 5740 #undef __ |
| 5728 | 5741 |
| 5729 } } // namespace v8::internal | 5742 } } // namespace v8::internal |
| OLD | NEW |