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 |