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