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 3180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3191 LLoadExternalArrayPointer* instr) { | 3191 LLoadExternalArrayPointer* instr) { |
3192 Register result = ToRegister(instr->result()); | 3192 Register result = ToRegister(instr->result()); |
3193 Register input = ToRegister(instr->object()); | 3193 Register input = ToRegister(instr->object()); |
3194 __ mov(result, FieldOperand(input, | 3194 __ mov(result, FieldOperand(input, |
3195 ExternalArray::kExternalPointerOffset)); | 3195 ExternalArray::kExternalPointerOffset)); |
3196 } | 3196 } |
3197 | 3197 |
3198 | 3198 |
3199 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 3199 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
3200 Register arguments = ToRegister(instr->arguments()); | 3200 Register arguments = ToRegister(instr->arguments()); |
3201 Register length = ToRegister(instr->length()); | |
3202 Operand index = ToOperand(instr->index()); | |
3203 Register result = ToRegister(instr->result()); | 3201 Register result = ToRegister(instr->result()); |
3204 // There are two words between the frame pointer and the last argument. | 3202 if (instr->length()->IsConstantOperand() && |
3205 // Subtracting from length accounts for one of them add one more. | 3203 instr->index()->IsConstantOperand()) { |
3206 __ sub(length, index); | 3204 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
3207 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); | 3205 int const_length = ToInteger32(LConstantOperand::cast(instr->length())); |
| 3206 int index = (const_length - const_index) + 1; |
| 3207 __ mov(result, Operand(arguments, index * kPointerSize)); |
| 3208 } else { |
| 3209 Register length = ToRegister(instr->length()); |
| 3210 Operand index = ToOperand(instr->index()); |
| 3211 // There are two words between the frame pointer and the last argument. |
| 3212 // Subtracting from length accounts for one of them add one more. |
| 3213 __ sub(length, index); |
| 3214 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); |
| 3215 } |
3208 } | 3216 } |
3209 | 3217 |
3210 | 3218 |
3211 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3219 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
3212 ElementsKind elements_kind = instr->elements_kind(); | 3220 ElementsKind elements_kind = instr->elements_kind(); |
3213 LOperand* key = instr->key(); | 3221 LOperand* key = instr->key(); |
3214 if (!key->IsConstantOperand() && | 3222 if (!key->IsConstantOperand() && |
3215 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), | 3223 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
3216 elements_kind)) { | 3224 elements_kind)) { |
3217 __ SmiUntag(ToRegister(key)); | 3225 __ SmiUntag(ToRegister(key)); |
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4215 | 4223 |
4216 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 4224 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
4217 Register result = ToRegister(instr->result()); | 4225 Register result = ToRegister(instr->result()); |
4218 Register base = ToRegister(instr->base_object()); | 4226 Register base = ToRegister(instr->base_object()); |
4219 __ lea(result, Operand(base, instr->offset())); | 4227 __ lea(result, Operand(base, instr->offset())); |
4220 } | 4228 } |
4221 | 4229 |
4222 | 4230 |
4223 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 4231 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
4224 Register object = ToRegister(instr->object()); | 4232 Register object = ToRegister(instr->object()); |
4225 Register value = ToRegister(instr->value()); | |
4226 int offset = instr->offset(); | 4233 int offset = instr->offset(); |
4227 | 4234 |
4228 if (!instr->transition().is_null()) { | 4235 if (!instr->transition().is_null()) { |
4229 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { | 4236 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { |
4230 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); | 4237 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); |
4231 } else { | 4238 } else { |
4232 Register temp = ToRegister(instr->temp()); | 4239 Register temp = ToRegister(instr->temp()); |
4233 Register temp_map = ToRegister(instr->temp_map()); | 4240 Register temp_map = ToRegister(instr->temp_map()); |
4234 __ mov(temp_map, instr->transition()); | 4241 __ mov(temp_map, instr->transition()); |
4235 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); | 4242 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); |
4236 // Update the write barrier for the map field. | 4243 // Update the write barrier for the map field. |
4237 __ RecordWriteField(object, | 4244 __ RecordWriteField(object, |
4238 HeapObject::kMapOffset, | 4245 HeapObject::kMapOffset, |
4239 temp_map, | 4246 temp_map, |
4240 temp, | 4247 temp, |
4241 GetSaveFPRegsMode(), | 4248 GetSaveFPRegsMode(), |
4242 OMIT_REMEMBERED_SET, | 4249 OMIT_REMEMBERED_SET, |
4243 OMIT_SMI_CHECK); | 4250 OMIT_SMI_CHECK); |
4244 } | 4251 } |
4245 } | 4252 } |
4246 | 4253 |
4247 // Do the store. | 4254 // Do the store. |
4248 HType type = instr->hydrogen()->value()->type(); | 4255 HType type = instr->hydrogen()->value()->type(); |
4249 SmiCheck check_needed = | 4256 SmiCheck check_needed = |
4250 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4257 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4251 if (instr->is_in_object()) { | 4258 |
4252 __ mov(FieldOperand(object, offset), value); | 4259 Register write_register = object; |
4253 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4260 if (!instr->is_in_object()) { |
4254 Register temp = ToRegister(instr->temp()); | 4261 write_register = ToRegister(instr->temp()); |
4255 // Update the write barrier for the object for in-object properties. | 4262 __ mov(write_register, |
4256 __ RecordWriteField(object, | 4263 FieldOperand(object, JSObject::kPropertiesOffset)); |
4257 offset, | 4264 } |
4258 value, | 4265 |
4259 temp, | 4266 if (instr->value()->IsConstantOperand()) { |
4260 GetSaveFPRegsMode(), | 4267 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
4261 EMIT_REMEMBERED_SET, | 4268 if (IsInteger32(operand_value)) { |
4262 check_needed); | 4269 int const_value = ToInteger32(operand_value); |
| 4270 __ mov(FieldOperand(write_register, offset), Immediate(const_value)); |
| 4271 } else { |
| 4272 if (operand_value->IsRegister()) { |
| 4273 __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); |
| 4274 } else { |
| 4275 Handle<Object> handle_value = ToHandle(operand_value); |
| 4276 __ mov(FieldOperand(write_register, offset), handle_value); |
| 4277 } |
4263 } | 4278 } |
4264 } else { | 4279 } else { |
4265 Register temp = ToRegister(instr->temp()); | 4280 __ mov(FieldOperand(write_register, offset), ToRegister(instr->value())); |
4266 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); | 4281 } |
4267 __ mov(FieldOperand(temp, offset), value); | 4282 |
4268 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4283 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4269 // Update the write barrier for the properties array. | 4284 Register value = ToRegister(instr->value()); |
4270 // object is used as a scratch register. | 4285 Register temp = instr->is_in_object() ? ToRegister(instr->temp()) : object; |
4271 __ RecordWriteField(temp, | 4286 // Update the write barrier for the object for in-object properties. |
4272 offset, | 4287 __ RecordWriteField(write_register, |
4273 value, | 4288 offset, |
4274 object, | 4289 value, |
4275 GetSaveFPRegsMode(), | 4290 temp, |
4276 EMIT_REMEMBERED_SET, | 4291 GetSaveFPRegsMode(), |
4277 check_needed); | 4292 EMIT_REMEMBERED_SET, |
4278 } | 4293 check_needed); |
4279 } | 4294 } |
4280 } | 4295 } |
4281 | 4296 |
4282 | 4297 |
4283 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 4298 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
4284 ASSERT(ToRegister(instr->context()).is(esi)); | 4299 ASSERT(ToRegister(instr->context()).is(esi)); |
4285 ASSERT(ToRegister(instr->object()).is(edx)); | 4300 ASSERT(ToRegister(instr->object()).is(edx)); |
4286 ASSERT(ToRegister(instr->value()).is(eax)); | 4301 ASSERT(ToRegister(instr->value()).is(eax)); |
4287 | 4302 |
4288 __ mov(ecx, instr->name()); | 4303 __ mov(ecx, instr->name()); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4446 } | 4461 } |
4447 | 4462 |
4448 __ bind(&no_special_nan_handling); | 4463 __ bind(&no_special_nan_handling); |
4449 __ fst_d(double_store_operand); | 4464 __ fst_d(double_store_operand); |
4450 } | 4465 } |
4451 } | 4466 } |
4452 } | 4467 } |
4453 | 4468 |
4454 | 4469 |
4455 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4470 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
4456 Register value = ToRegister(instr->value()); | |
4457 Register elements = ToRegister(instr->elements()); | 4471 Register elements = ToRegister(instr->elements()); |
4458 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 4472 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
4459 | 4473 |
4460 Operand operand = BuildFastArrayOperand( | 4474 Operand operand = BuildFastArrayOperand( |
4461 instr->elements(), | 4475 instr->elements(), |
4462 instr->key(), | 4476 instr->key(), |
4463 instr->hydrogen()->key()->representation(), | 4477 instr->hydrogen()->key()->representation(), |
4464 FAST_ELEMENTS, | 4478 FAST_ELEMENTS, |
4465 FixedArray::kHeaderSize - kHeapObjectTag, | 4479 FixedArray::kHeaderSize - kHeapObjectTag, |
4466 instr->additional_index()); | 4480 instr->additional_index()); |
4467 __ mov(operand, value); | 4481 if (instr->value()->IsRegister()) { |
| 4482 __ mov(operand, ToRegister(instr->value())); |
| 4483 } else { |
| 4484 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4485 if (IsInteger32(operand_value)) { |
| 4486 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); |
| 4487 __ mov(operand, Immediate(smi_value)); |
| 4488 } else { |
| 4489 Handle<Object> handle_value = ToHandle(operand_value); |
| 4490 __ mov(operand, handle_value); |
| 4491 } |
| 4492 } |
4468 | 4493 |
4469 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4494 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4495 ASSERT(instr->value()->IsRegister()); |
| 4496 Register value = ToRegister(instr->value()); |
4470 ASSERT(!instr->key()->IsConstantOperand()); | 4497 ASSERT(!instr->key()->IsConstantOperand()); |
4471 HType type = instr->hydrogen()->value()->type(); | 4498 HType type = instr->hydrogen()->value()->type(); |
4472 SmiCheck check_needed = | 4499 SmiCheck check_needed = |
4473 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4500 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4474 // Compute address of modified element and store it into key register. | 4501 // Compute address of modified element and store it into key register. |
4475 __ lea(key, operand); | 4502 __ lea(key, operand); |
4476 __ RecordWrite(elements, | 4503 __ RecordWrite(elements, |
4477 key, | 4504 key, |
4478 value, | 4505 value, |
4479 GetSaveFPRegsMode(), | 4506 GetSaveFPRegsMode(), |
(...skipping 2071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6551 FixedArray::kHeaderSize - kPointerSize)); | 6578 FixedArray::kHeaderSize - kPointerSize)); |
6552 __ bind(&done); | 6579 __ bind(&done); |
6553 } | 6580 } |
6554 | 6581 |
6555 | 6582 |
6556 #undef __ | 6583 #undef __ |
6557 | 6584 |
6558 } } // namespace v8::internal | 6585 } } // namespace v8::internal |
6559 | 6586 |
6560 #endif // V8_TARGET_ARCH_IA32 | 6587 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |