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 22 matching lines...) Expand all Loading... |
33 #include "ic.h" | 33 #include "ic.h" |
34 #include "code-stubs.h" | 34 #include "code-stubs.h" |
35 #include "deoptimizer.h" | 35 #include "deoptimizer.h" |
36 #include "stub-cache.h" | 36 #include "stub-cache.h" |
37 #include "codegen.h" | 37 #include "codegen.h" |
38 | 38 |
39 namespace v8 { | 39 namespace v8 { |
40 namespace internal { | 40 namespace internal { |
41 | 41 |
42 | 42 |
| 43 static SaveFPRegsMode GetSaveFPRegsMode() { |
| 44 // We don't need to save floating point regs when generating the snapshot |
| 45 return CpuFeatures::IsSafeForSnapshot(SSE2) ? kSaveFPRegs : kDontSaveFPRegs; |
| 46 } |
| 47 |
| 48 |
43 // When invoking builtins, we need to record the safepoint in the middle of | 49 // When invoking builtins, we need to record the safepoint in the middle of |
44 // the invoke instruction sequence generated by the macro assembler. | 50 // the invoke instruction sequence generated by the macro assembler. |
45 class SafepointGenerator : public CallWrapper { | 51 class SafepointGenerator : public CallWrapper { |
46 public: | 52 public: |
47 SafepointGenerator(LCodeGen* codegen, | 53 SafepointGenerator(LCodeGen* codegen, |
48 LPointerMap* pointers, | 54 LPointerMap* pointers, |
49 Safepoint::DeoptMode mode) | 55 Safepoint::DeoptMode mode) |
50 : codegen_(codegen), | 56 : codegen_(codegen), |
51 pointers_(pointers), | 57 pointers_(pointers), |
52 deopt_mode_(mode) {} | 58 deopt_mode_(mode) {} |
(...skipping 2787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2840 if (instr->hydrogen()->NeedsWriteBarrier()) { | 2846 if (instr->hydrogen()->NeedsWriteBarrier()) { |
2841 HType type = instr->hydrogen()->value()->type(); | 2847 HType type = instr->hydrogen()->value()->type(); |
2842 SmiCheck check_needed = | 2848 SmiCheck check_needed = |
2843 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 2849 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
2844 Register temp = ToRegister(instr->temp()); | 2850 Register temp = ToRegister(instr->temp()); |
2845 int offset = Context::SlotOffset(instr->slot_index()); | 2851 int offset = Context::SlotOffset(instr->slot_index()); |
2846 __ RecordWriteContextSlot(context, | 2852 __ RecordWriteContextSlot(context, |
2847 offset, | 2853 offset, |
2848 value, | 2854 value, |
2849 temp, | 2855 temp, |
2850 kSaveFPRegs, | 2856 GetSaveFPRegsMode(), |
2851 EMIT_REMEMBERED_SET, | 2857 EMIT_REMEMBERED_SET, |
2852 check_needed); | 2858 check_needed); |
2853 } | 2859 } |
2854 | 2860 |
2855 __ bind(&skip_assignment); | 2861 __ bind(&skip_assignment); |
2856 } | 2862 } |
2857 | 2863 |
2858 | 2864 |
2859 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2865 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
2860 Register object = ToRegister(instr->object()); | 2866 Register object = ToRegister(instr->object()); |
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4172 } else { | 4178 } else { |
4173 Register temp = ToRegister(instr->temp()); | 4179 Register temp = ToRegister(instr->temp()); |
4174 Register temp_map = ToRegister(instr->temp_map()); | 4180 Register temp_map = ToRegister(instr->temp_map()); |
4175 __ mov(temp_map, instr->transition()); | 4181 __ mov(temp_map, instr->transition()); |
4176 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); | 4182 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); |
4177 // Update the write barrier for the map field. | 4183 // Update the write barrier for the map field. |
4178 __ RecordWriteField(object, | 4184 __ RecordWriteField(object, |
4179 HeapObject::kMapOffset, | 4185 HeapObject::kMapOffset, |
4180 temp_map, | 4186 temp_map, |
4181 temp, | 4187 temp, |
4182 kSaveFPRegs, | 4188 GetSaveFPRegsMode(), |
4183 OMIT_REMEMBERED_SET, | 4189 OMIT_REMEMBERED_SET, |
4184 OMIT_SMI_CHECK); | 4190 OMIT_SMI_CHECK); |
4185 } | 4191 } |
4186 } | 4192 } |
4187 | 4193 |
4188 // Do the store. | 4194 // Do the store. |
4189 HType type = instr->hydrogen()->value()->type(); | 4195 HType type = instr->hydrogen()->value()->type(); |
4190 SmiCheck check_needed = | 4196 SmiCheck check_needed = |
4191 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4197 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4192 if (instr->is_in_object()) { | 4198 if (instr->is_in_object()) { |
4193 __ mov(FieldOperand(object, offset), value); | 4199 __ mov(FieldOperand(object, offset), value); |
4194 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4200 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4195 Register temp = ToRegister(instr->temp()); | 4201 Register temp = ToRegister(instr->temp()); |
4196 // Update the write barrier for the object for in-object properties. | 4202 // Update the write barrier for the object for in-object properties. |
4197 __ RecordWriteField(object, | 4203 __ RecordWriteField(object, |
4198 offset, | 4204 offset, |
4199 value, | 4205 value, |
4200 temp, | 4206 temp, |
4201 kSaveFPRegs, | 4207 GetSaveFPRegsMode(), |
4202 EMIT_REMEMBERED_SET, | 4208 EMIT_REMEMBERED_SET, |
4203 check_needed); | 4209 check_needed); |
4204 } | 4210 } |
4205 } else { | 4211 } else { |
4206 Register temp = ToRegister(instr->temp()); | 4212 Register temp = ToRegister(instr->temp()); |
4207 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); | 4213 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); |
4208 __ mov(FieldOperand(temp, offset), value); | 4214 __ mov(FieldOperand(temp, offset), value); |
4209 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4215 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4210 // Update the write barrier for the properties array. | 4216 // Update the write barrier for the properties array. |
4211 // object is used as a scratch register. | 4217 // object is used as a scratch register. |
4212 __ RecordWriteField(temp, | 4218 __ RecordWriteField(temp, |
4213 offset, | 4219 offset, |
4214 value, | 4220 value, |
4215 object, | 4221 object, |
4216 kSaveFPRegs, | 4222 GetSaveFPRegsMode(), |
4217 EMIT_REMEMBERED_SET, | 4223 EMIT_REMEMBERED_SET, |
4218 check_needed); | 4224 check_needed); |
4219 } | 4225 } |
4220 } | 4226 } |
4221 } | 4227 } |
4222 | 4228 |
4223 | 4229 |
4224 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 4230 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
4225 ASSERT(ToRegister(instr->context()).is(esi)); | 4231 ASSERT(ToRegister(instr->context()).is(esi)); |
4226 ASSERT(ToRegister(instr->object()).is(edx)); | 4232 ASSERT(ToRegister(instr->object()).is(edx)); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4353 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4359 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4354 ASSERT(!instr->key()->IsConstantOperand()); | 4360 ASSERT(!instr->key()->IsConstantOperand()); |
4355 HType type = instr->hydrogen()->value()->type(); | 4361 HType type = instr->hydrogen()->value()->type(); |
4356 SmiCheck check_needed = | 4362 SmiCheck check_needed = |
4357 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4363 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4358 // Compute address of modified element and store it into key register. | 4364 // Compute address of modified element and store it into key register. |
4359 __ lea(key, operand); | 4365 __ lea(key, operand); |
4360 __ RecordWrite(elements, | 4366 __ RecordWrite(elements, |
4361 key, | 4367 key, |
4362 value, | 4368 value, |
4363 kSaveFPRegs, | 4369 GetSaveFPRegsMode(), |
4364 EMIT_REMEMBERED_SET, | 4370 EMIT_REMEMBERED_SET, |
4365 check_needed); | 4371 check_needed); |
4366 } | 4372 } |
4367 } | 4373 } |
4368 | 4374 |
4369 | 4375 |
4370 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4376 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
4371 // By cases...external, fast-double, fast | 4377 // By cases...external, fast-double, fast |
4372 if (instr->is_external()) { | 4378 if (instr->is_external()) { |
4373 DoStoreKeyedExternalArray(instr); | 4379 DoStoreKeyedExternalArray(instr); |
(...skipping 1879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6253 FixedArray::kHeaderSize - kPointerSize)); | 6259 FixedArray::kHeaderSize - kPointerSize)); |
6254 __ bind(&done); | 6260 __ bind(&done); |
6255 } | 6261 } |
6256 | 6262 |
6257 | 6263 |
6258 #undef __ | 6264 #undef __ |
6259 | 6265 |
6260 } } // namespace v8::internal | 6266 } } // namespace v8::internal |
6261 | 6267 |
6262 #endif // V8_TARGET_ARCH_IA32 | 6268 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |