| 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 |