Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 12385014: Hydrogen stubs for array constructors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More efficient code when number of arguments is known Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698