| 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 GenerateDeferredCode() && | 95 GenerateDeferredCode() && |
| 96 GenerateJumpTable() && | 96 GenerateJumpTable() && |
| 97 GenerateSafepointTable(); | 97 GenerateSafepointTable(); |
| 98 } | 98 } |
| 99 | 99 |
| 100 | 100 |
| 101 void LCodeGen::FinishCode(Handle<Code> code) { | 101 void LCodeGen::FinishCode(Handle<Code> code) { |
| 102 ASSERT(is_done()); | 102 ASSERT(is_done()); |
| 103 code->set_stack_slots(GetStackSlotCount()); | 103 code->set_stack_slots(GetStackSlotCount()); |
| 104 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 104 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 105 if (FLAG_weak_embedded_maps_in_optimized_code) { | 105 if (FLAG_weak_embedded_maps_in_optimized_code && |
| 106 code->kind() == Code::OPTIMIZED_FUNCTION) { |
| 106 RegisterDependentCodeForEmbeddedMaps(code); | 107 RegisterDependentCodeForEmbeddedMaps(code); |
| 107 } | 108 } |
| 108 PopulateDeoptimizationData(code); | 109 PopulateDeoptimizationData(code); |
| 109 if (!info()->IsStub()) { | 110 if (!info()->IsStub()) { |
| 110 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); | 111 Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); |
| 111 } | 112 } |
| 112 for (int i = 0 ; i < prototype_maps_.length(); i++) { | 113 for (int i = 0 ; i < prototype_maps_.length(); i++) { |
| 113 prototype_maps_.at(i)->AddDependentCode( | 114 prototype_maps_.at(i)->AddDependentCode( |
| 114 DependentCode::kPrototypeCheckGroup, code); | 115 DependentCode::kPrototypeCheckGroup, code); |
| 115 } | 116 } |
| (...skipping 2661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2777 int parameter_count = ToInteger32(instr->constant_parameter_count()); | 2778 int parameter_count = ToInteger32(instr->constant_parameter_count()); |
| 2778 if (dynamic_frame_alignment && FLAG_debug_code) { | 2779 if (dynamic_frame_alignment && FLAG_debug_code) { |
| 2779 __ cmp(Operand(esp, | 2780 __ cmp(Operand(esp, |
| 2780 (parameter_count + extra_value_count) * kPointerSize), | 2781 (parameter_count + extra_value_count) * kPointerSize), |
| 2781 Immediate(kAlignmentZapValue)); | 2782 Immediate(kAlignmentZapValue)); |
| 2782 __ Assert(equal, "expected alignment marker"); | 2783 __ Assert(equal, "expected alignment marker"); |
| 2783 } | 2784 } |
| 2784 __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx); | 2785 __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx); |
| 2785 } else { | 2786 } else { |
| 2786 Register reg = ToRegister(instr->parameter_count()); | 2787 Register reg = ToRegister(instr->parameter_count()); |
| 2788 __ SmiUntag(reg); // it is a smi |
| 2787 Register return_addr_reg = reg.is(ecx) ? ebx : ecx; | 2789 Register return_addr_reg = reg.is(ecx) ? ebx : ecx; |
| 2788 if (dynamic_frame_alignment && FLAG_debug_code) { | 2790 if (dynamic_frame_alignment && FLAG_debug_code) { |
| 2789 ASSERT(extra_value_count == 2); | 2791 ASSERT(extra_value_count == 2); |
| 2790 __ cmp(Operand(esp, reg, times_pointer_size, | 2792 __ cmp(Operand(esp, reg, times_pointer_size, |
| 2791 extra_value_count * kPointerSize), | 2793 extra_value_count * kPointerSize), |
| 2792 Immediate(kAlignmentZapValue)); | 2794 Immediate(kAlignmentZapValue)); |
| 2793 __ Assert(equal, "expected alignment marker"); | 2795 __ Assert(equal, "expected alignment marker"); |
| 2794 } | 2796 } |
| 2795 | 2797 |
| 2796 // emit code to restore stack based on instr->parameter_count() | 2798 // emit code to restore stack based on instr->parameter_count() |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3189 LLoadExternalArrayPointer* instr) { | 3191 LLoadExternalArrayPointer* instr) { |
| 3190 Register result = ToRegister(instr->result()); | 3192 Register result = ToRegister(instr->result()); |
| 3191 Register input = ToRegister(instr->object()); | 3193 Register input = ToRegister(instr->object()); |
| 3192 __ mov(result, FieldOperand(input, | 3194 __ mov(result, FieldOperand(input, |
| 3193 ExternalArray::kExternalPointerOffset)); | 3195 ExternalArray::kExternalPointerOffset)); |
| 3194 } | 3196 } |
| 3195 | 3197 |
| 3196 | 3198 |
| 3197 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { | 3199 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
| 3198 Register arguments = ToRegister(instr->arguments()); | 3200 Register arguments = ToRegister(instr->arguments()); |
| 3199 Register length = ToRegister(instr->length()); | |
| 3200 Operand index = ToOperand(instr->index()); | |
| 3201 Register result = ToRegister(instr->result()); | 3201 Register result = ToRegister(instr->result()); |
| 3202 // There are two words between the frame pointer and the last argument. | 3202 if (instr->length()->IsConstantOperand() && |
| 3203 // Subtracting from length accounts for one of them add one more. | 3203 instr->index()->IsConstantOperand()) { |
| 3204 __ sub(length, index); | 3204 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); |
| 3205 __ 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 } |
| 3206 } | 3216 } |
| 3207 | 3217 |
| 3208 | 3218 |
| 3209 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3219 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 3210 ElementsKind elements_kind = instr->elements_kind(); | 3220 ElementsKind elements_kind = instr->elements_kind(); |
| 3211 LOperand* key = instr->key(); | 3221 LOperand* key = instr->key(); |
| 3212 if (!key->IsConstantOperand() && | 3222 if (!key->IsConstantOperand() && |
| 3213 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), | 3223 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), |
| 3214 elements_kind)) { | 3224 elements_kind)) { |
| 3215 __ SmiUntag(ToRegister(key)); | 3225 __ SmiUntag(ToRegister(key)); |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4191 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4201 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4192 } | 4202 } |
| 4193 | 4203 |
| 4194 | 4204 |
| 4195 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 4205 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
| 4196 ASSERT(ToRegister(instr->context()).is(esi)); | 4206 ASSERT(ToRegister(instr->context()).is(esi)); |
| 4197 ASSERT(ToRegister(instr->constructor()).is(edi)); | 4207 ASSERT(ToRegister(instr->constructor()).is(edi)); |
| 4198 ASSERT(ToRegister(instr->result()).is(eax)); | 4208 ASSERT(ToRegister(instr->result()).is(eax)); |
| 4199 ASSERT(FLAG_optimize_constructed_arrays); | 4209 ASSERT(FLAG_optimize_constructed_arrays); |
| 4200 | 4210 |
| 4211 __ Set(eax, Immediate(instr->arity())); |
| 4201 __ mov(ebx, instr->hydrogen()->property_cell()); | 4212 __ mov(ebx, instr->hydrogen()->property_cell()); |
| 4202 Handle<Code> array_construct_code = | 4213 ArrayConstructorStub stub(isolate(), instr->arity()); |
| 4203 isolate()->builtins()->ArrayConstructCode(); | 4214 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); |
| 4204 __ Set(eax, Immediate(instr->arity())); | |
| 4205 CallCode(array_construct_code, RelocInfo::CONSTRUCT_CALL, instr); | |
| 4206 } | 4215 } |
| 4207 | 4216 |
| 4208 | 4217 |
| 4209 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 4218 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
| 4210 CallRuntime(instr->function(), instr->arity(), instr); | 4219 CallRuntime(instr->function(), instr->arity(), instr); |
| 4211 } | 4220 } |
| 4212 | 4221 |
| 4213 | 4222 |
| 4214 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { | 4223 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
| 4215 Register result = ToRegister(instr->result()); | 4224 Register result = ToRegister(instr->result()); |
| 4216 Register base = ToRegister(instr->base_object()); | 4225 Register base = ToRegister(instr->base_object()); |
| 4217 __ lea(result, Operand(base, instr->offset())); | 4226 __ lea(result, Operand(base, instr->offset())); |
| 4218 } | 4227 } |
| 4219 | 4228 |
| 4220 | 4229 |
| 4221 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 4230 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 4222 Register object = ToRegister(instr->object()); | 4231 Register object = ToRegister(instr->object()); |
| 4223 Register value = ToRegister(instr->value()); | |
| 4224 int offset = instr->offset(); | 4232 int offset = instr->offset(); |
| 4225 | 4233 |
| 4226 if (!instr->transition().is_null()) { | 4234 if (!instr->transition().is_null()) { |
| 4227 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { | 4235 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { |
| 4228 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); | 4236 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); |
| 4229 } else { | 4237 } else { |
| 4230 Register temp = ToRegister(instr->temp()); | 4238 Register temp = ToRegister(instr->temp()); |
| 4231 Register temp_map = ToRegister(instr->temp_map()); | 4239 Register temp_map = ToRegister(instr->temp_map()); |
| 4232 __ mov(temp_map, instr->transition()); | 4240 __ mov(temp_map, instr->transition()); |
| 4233 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); | 4241 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); |
| 4234 // Update the write barrier for the map field. | 4242 // Update the write barrier for the map field. |
| 4235 __ RecordWriteField(object, | 4243 __ RecordWriteField(object, |
| 4236 HeapObject::kMapOffset, | 4244 HeapObject::kMapOffset, |
| 4237 temp_map, | 4245 temp_map, |
| 4238 temp, | 4246 temp, |
| 4239 GetSaveFPRegsMode(), | 4247 GetSaveFPRegsMode(), |
| 4240 OMIT_REMEMBERED_SET, | 4248 OMIT_REMEMBERED_SET, |
| 4241 OMIT_SMI_CHECK); | 4249 OMIT_SMI_CHECK); |
| 4242 } | 4250 } |
| 4243 } | 4251 } |
| 4244 | 4252 |
| 4245 // Do the store. | 4253 // Do the store. |
| 4246 HType type = instr->hydrogen()->value()->type(); | 4254 HType type = instr->hydrogen()->value()->type(); |
| 4247 SmiCheck check_needed = | 4255 SmiCheck check_needed = |
| 4248 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4256 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4249 if (instr->is_in_object()) { | 4257 if (instr->is_in_object()) { |
| 4250 __ mov(FieldOperand(object, offset), value); | 4258 if (instr->value()->IsConstantOperand()) { |
| 4259 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4260 if (IsInteger32(operand_value)) { |
| 4261 int const_value = ToInteger32(operand_value); |
| 4262 __ mov(FieldOperand(object, offset), Immediate(const_value)); |
| 4263 } else { |
| 4264 if (operand_value->IsRegister()) { |
| 4265 __ mov(FieldOperand(object, offset), ToRegister(operand_value)); |
| 4266 } else { |
| 4267 Handle<Object> handle_value = ToHandle(operand_value); |
| 4268 __ mov(FieldOperand(object, offset), handle_value); |
| 4269 } |
| 4270 } |
| 4271 } else { |
| 4272 __ mov(FieldOperand(object, offset), ToRegister(instr->value())); |
| 4273 } |
| 4274 |
| 4251 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4275 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4276 Register value = ToRegister(instr->value()); |
| 4252 Register temp = ToRegister(instr->temp()); | 4277 Register temp = ToRegister(instr->temp()); |
| 4253 // Update the write barrier for the object for in-object properties. | 4278 // Update the write barrier for the object for in-object properties. |
| 4254 __ RecordWriteField(object, | 4279 __ RecordWriteField(object, |
| 4255 offset, | 4280 offset, |
| 4256 value, | 4281 value, |
| 4257 temp, | 4282 temp, |
| 4258 GetSaveFPRegsMode(), | 4283 GetSaveFPRegsMode(), |
| 4259 EMIT_REMEMBERED_SET, | 4284 EMIT_REMEMBERED_SET, |
| 4260 check_needed); | 4285 check_needed); |
| 4261 } | 4286 } |
| 4262 } else { | 4287 } else { |
| 4263 Register temp = ToRegister(instr->temp()); | 4288 Register temp = ToRegister(instr->temp()); |
| 4264 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); | 4289 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); |
| 4265 __ mov(FieldOperand(temp, offset), value); | 4290 |
| 4291 if (instr->value()->IsConstantOperand()) { |
| 4292 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4293 if (IsInteger32(operand_value)) { |
| 4294 int const_value = ToInteger32(operand_value); |
| 4295 __ mov(FieldOperand(temp, offset), Immediate(const_value)); |
| 4296 } else { |
| 4297 if (operand_value->IsRegister()) { |
| 4298 __ mov(FieldOperand(temp, offset), ToRegister(operand_value)); |
| 4299 } else { |
| 4300 Handle<Object> handle_value = ToHandle(operand_value); |
| 4301 __ mov(FieldOperand(temp, offset), handle_value); |
| 4302 } |
| 4303 } |
| 4304 } else { |
| 4305 __ mov(FieldOperand(temp, offset), ToRegister(instr->value())); |
| 4306 } |
| 4307 |
| 4266 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4308 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4309 Register value = ToRegister(instr->value()); |
| 4267 // Update the write barrier for the properties array. | 4310 // Update the write barrier for the properties array. |
| 4268 // object is used as a scratch register. | 4311 // object is used as a scratch register. |
| 4269 __ RecordWriteField(temp, | 4312 __ RecordWriteField(temp, |
| 4270 offset, | 4313 offset, |
| 4271 value, | 4314 value, |
| 4272 object, | 4315 object, |
| 4273 GetSaveFPRegsMode(), | 4316 GetSaveFPRegsMode(), |
| 4274 EMIT_REMEMBERED_SET, | 4317 EMIT_REMEMBERED_SET, |
| 4275 check_needed); | 4318 check_needed); |
| 4276 } | 4319 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4444 } | 4487 } |
| 4445 | 4488 |
| 4446 __ bind(&no_special_nan_handling); | 4489 __ bind(&no_special_nan_handling); |
| 4447 __ fst_d(double_store_operand); | 4490 __ fst_d(double_store_operand); |
| 4448 } | 4491 } |
| 4449 } | 4492 } |
| 4450 } | 4493 } |
| 4451 | 4494 |
| 4452 | 4495 |
| 4453 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4496 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4454 Register value = ToRegister(instr->value()); | |
| 4455 Register elements = ToRegister(instr->elements()); | 4497 Register elements = ToRegister(instr->elements()); |
| 4456 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; | 4498 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
| 4457 | 4499 |
| 4458 Operand operand = BuildFastArrayOperand( | 4500 Operand operand = BuildFastArrayOperand( |
| 4459 instr->elements(), | 4501 instr->elements(), |
| 4460 instr->key(), | 4502 instr->key(), |
| 4461 instr->hydrogen()->key()->representation(), | 4503 instr->hydrogen()->key()->representation(), |
| 4462 FAST_ELEMENTS, | 4504 FAST_ELEMENTS, |
| 4463 FixedArray::kHeaderSize - kHeapObjectTag, | 4505 FixedArray::kHeaderSize - kHeapObjectTag, |
| 4464 instr->additional_index()); | 4506 instr->additional_index()); |
| 4465 __ mov(operand, value); | 4507 if (instr->value()->IsRegister()) { |
| 4508 __ mov(operand, ToRegister(instr->value())); |
| 4509 } else { |
| 4510 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4511 if (IsInteger32(operand_value)) { |
| 4512 int const_value = ToInteger32(operand_value); |
| 4513 __ mov(operand, Immediate(const_value)); |
| 4514 } else { |
| 4515 Handle<Object> handle_value = ToHandle(operand_value); |
| 4516 __ mov(operand, handle_value); |
| 4517 } |
| 4518 } |
| 4466 | 4519 |
| 4467 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4520 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 4521 ASSERT(instr->value()->IsRegister()); |
| 4522 Register value = ToRegister(instr->value()); |
| 4468 ASSERT(!instr->key()->IsConstantOperand()); | 4523 ASSERT(!instr->key()->IsConstantOperand()); |
| 4469 HType type = instr->hydrogen()->value()->type(); | 4524 HType type = instr->hydrogen()->value()->type(); |
| 4470 SmiCheck check_needed = | 4525 SmiCheck check_needed = |
| 4471 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4526 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| 4472 // Compute address of modified element and store it into key register. | 4527 // Compute address of modified element and store it into key register. |
| 4473 __ lea(key, operand); | 4528 __ lea(key, operand); |
| 4474 __ RecordWrite(elements, | 4529 __ RecordWrite(elements, |
| 4475 key, | 4530 key, |
| 4476 value, | 4531 value, |
| 4477 GetSaveFPRegsMode(), | 4532 GetSaveFPRegsMode(), |
| (...skipping 2066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6544 FixedArray::kHeaderSize - kPointerSize)); | 6599 FixedArray::kHeaderSize - kPointerSize)); |
| 6545 __ bind(&done); | 6600 __ bind(&done); |
| 6546 } | 6601 } |
| 6547 | 6602 |
| 6548 | 6603 |
| 6549 #undef __ | 6604 #undef __ |
| 6550 | 6605 |
| 6551 } } // namespace v8::internal | 6606 } } // namespace v8::internal |
| 6552 | 6607 |
| 6553 #endif // V8_TARGET_ARCH_IA32 | 6608 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |