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

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: With all ports done 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 Object* cell_value = instr->hydrogen()->property_cell()->value();
4203 isolate()->builtins()->ArrayConstructCode(); 4214 ElementsKind kind = static_cast<ElementsKind>(Smi::cast(cell_value)->value());
4204 __ Set(eax, Immediate(instr->arity())); 4215 if (instr->arity() == 0) {
4205 CallCode(array_construct_code, RelocInfo::CONSTRUCT_CALL, instr); 4216 ArrayNoArgumentConstructorStub stub(kind);
4217 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4218 } else if (instr->arity() == 1) {
4219 ArraySingleArgumentConstructorStub stub(kind);
4220 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4221 } else {
4222 ArrayNArgumentsConstructorStub stub(kind);
4223 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4224 }
4206 } 4225 }
4207 4226
4208 4227
4209 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4228 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4210 CallRuntime(instr->function(), instr->arity(), instr); 4229 CallRuntime(instr->function(), instr->arity(), instr);
4211 } 4230 }
4212 4231
4213 4232
4214 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 4233 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
4215 Register result = ToRegister(instr->result()); 4234 Register result = ToRegister(instr->result());
4216 Register base = ToRegister(instr->base_object()); 4235 Register base = ToRegister(instr->base_object());
4217 __ lea(result, Operand(base, instr->offset())); 4236 __ lea(result, Operand(base, instr->offset()));
4218 } 4237 }
4219 4238
4220 4239
4221 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 4240 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4222 Register object = ToRegister(instr->object()); 4241 Register object = ToRegister(instr->object());
4223 Register value = ToRegister(instr->value());
4224 int offset = instr->offset(); 4242 int offset = instr->offset();
4225 4243
4226 if (!instr->transition().is_null()) { 4244 if (!instr->transition().is_null()) {
4227 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 4245 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
4228 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition()); 4246 __ mov(FieldOperand(object, HeapObject::kMapOffset), instr->transition());
4229 } else { 4247 } else {
4230 Register temp = ToRegister(instr->temp()); 4248 Register temp = ToRegister(instr->temp());
4231 Register temp_map = ToRegister(instr->temp_map()); 4249 Register temp_map = ToRegister(instr->temp_map());
4232 __ mov(temp_map, instr->transition()); 4250 __ mov(temp_map, instr->transition());
4233 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); 4251 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map);
4234 // Update the write barrier for the map field. 4252 // Update the write barrier for the map field.
4235 __ RecordWriteField(object, 4253 __ RecordWriteField(object,
4236 HeapObject::kMapOffset, 4254 HeapObject::kMapOffset,
4237 temp_map, 4255 temp_map,
4238 temp, 4256 temp,
4239 GetSaveFPRegsMode(), 4257 GetSaveFPRegsMode(),
4240 OMIT_REMEMBERED_SET, 4258 OMIT_REMEMBERED_SET,
4241 OMIT_SMI_CHECK); 4259 OMIT_SMI_CHECK);
4242 } 4260 }
4243 } 4261 }
4244 4262
4245 // Do the store. 4263 // Do the store.
4246 HType type = instr->hydrogen()->value()->type(); 4264 HType type = instr->hydrogen()->value()->type();
4247 SmiCheck check_needed = 4265 SmiCheck check_needed =
4248 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4266 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4249 if (instr->is_in_object()) { 4267 if (instr->is_in_object()) {
4250 __ mov(FieldOperand(object, offset), value); 4268 if (instr->value()->IsConstantOperand()) {
4269 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4270 if (IsInteger32(operand_value)) {
4271 int const_value = ToInteger32(operand_value);
4272 __ mov(FieldOperand(object, offset), Immediate(const_value));
4273 } else {
4274 if (operand_value->IsRegister()) {
4275 __ mov(FieldOperand(object, offset), ToRegister(operand_value));
4276 } else {
4277 Handle<Object> handle_value = ToHandle(operand_value);
4278 __ mov(FieldOperand(object, offset), handle_value);
4279 }
4280 }
4281 } else {
4282 __ mov(FieldOperand(object, offset), ToRegister(instr->value()));
4283 }
4284
4251 if (instr->hydrogen()->NeedsWriteBarrier()) { 4285 if (instr->hydrogen()->NeedsWriteBarrier()) {
4286 Register value = ToRegister(instr->value());
4252 Register temp = ToRegister(instr->temp()); 4287 Register temp = ToRegister(instr->temp());
4253 // Update the write barrier for the object for in-object properties. 4288 // Update the write barrier for the object for in-object properties.
4254 __ RecordWriteField(object, 4289 __ RecordWriteField(object,
4255 offset, 4290 offset,
4256 value, 4291 value,
4257 temp, 4292 temp,
4258 GetSaveFPRegsMode(), 4293 GetSaveFPRegsMode(),
4259 EMIT_REMEMBERED_SET, 4294 EMIT_REMEMBERED_SET,
4260 check_needed); 4295 check_needed);
4261 } 4296 }
4262 } else { 4297 } else {
4263 Register temp = ToRegister(instr->temp()); 4298 Register temp = ToRegister(instr->temp());
4264 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 4299 __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset));
4265 __ mov(FieldOperand(temp, offset), value); 4300
4301 if (instr->value()->IsConstantOperand()) {
4302 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4303 if (IsInteger32(operand_value)) {
4304 int const_value = ToInteger32(operand_value);
4305 __ mov(FieldOperand(temp, offset), Immediate(const_value));
4306 } else {
4307 if (operand_value->IsRegister()) {
4308 __ mov(FieldOperand(temp, offset), ToRegister(operand_value));
4309 } else {
4310 Handle<Object> handle_value = ToHandle(operand_value);
4311 __ mov(FieldOperand(temp, offset), handle_value);
4312 }
4313 }
4314 } else {
4315 __ mov(FieldOperand(temp, offset), ToRegister(instr->value()));
4316 }
4317
4266 if (instr->hydrogen()->NeedsWriteBarrier()) { 4318 if (instr->hydrogen()->NeedsWriteBarrier()) {
4319 Register value = ToRegister(instr->value());
4267 // Update the write barrier for the properties array. 4320 // Update the write barrier for the properties array.
4268 // object is used as a scratch register. 4321 // object is used as a scratch register.
4269 __ RecordWriteField(temp, 4322 __ RecordWriteField(temp,
4270 offset, 4323 offset,
4271 value, 4324 value,
4272 object, 4325 object,
4273 GetSaveFPRegsMode(), 4326 GetSaveFPRegsMode(),
4274 EMIT_REMEMBERED_SET, 4327 EMIT_REMEMBERED_SET,
4275 check_needed); 4328 check_needed);
4276 } 4329 }
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
4444 } 4497 }
4445 4498
4446 __ bind(&no_special_nan_handling); 4499 __ bind(&no_special_nan_handling);
4447 __ fst_d(double_store_operand); 4500 __ fst_d(double_store_operand);
4448 } 4501 }
4449 } 4502 }
4450 } 4503 }
4451 4504
4452 4505
4453 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4506 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4454 Register value = ToRegister(instr->value());
4455 Register elements = ToRegister(instr->elements()); 4507 Register elements = ToRegister(instr->elements());
4456 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 4508 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
4457 4509
4458 Operand operand = BuildFastArrayOperand( 4510 Operand operand = BuildFastArrayOperand(
4459 instr->elements(), 4511 instr->elements(),
4460 instr->key(), 4512 instr->key(),
4461 instr->hydrogen()->key()->representation(), 4513 instr->hydrogen()->key()->representation(),
4462 FAST_ELEMENTS, 4514 FAST_ELEMENTS,
4463 FixedArray::kHeaderSize - kHeapObjectTag, 4515 FixedArray::kHeaderSize - kHeapObjectTag,
4464 instr->additional_index()); 4516 instr->additional_index());
4465 __ mov(operand, value); 4517 if (instr->value()->IsRegister()) {
4518 __ mov(operand, ToRegister(instr->value()));
4519 } else {
4520 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4521 if (IsInteger32(operand_value)) {
4522 int const_value = ToInteger32(operand_value);
4523 __ mov(operand, Immediate(const_value));
4524 } else {
4525 Handle<Object> handle_value = ToHandle(operand_value);
4526 __ mov(operand, handle_value);
4527 }
4528 }
4466 4529
4467 if (instr->hydrogen()->NeedsWriteBarrier()) { 4530 if (instr->hydrogen()->NeedsWriteBarrier()) {
4531 ASSERT(instr->value()->IsRegister());
4532 Register value = ToRegister(instr->value());
4468 ASSERT(!instr->key()->IsConstantOperand()); 4533 ASSERT(!instr->key()->IsConstantOperand());
4469 HType type = instr->hydrogen()->value()->type(); 4534 HType type = instr->hydrogen()->value()->type();
4470 SmiCheck check_needed = 4535 SmiCheck check_needed =
4471 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4536 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4472 // Compute address of modified element and store it into key register. 4537 // Compute address of modified element and store it into key register.
4473 __ lea(key, operand); 4538 __ lea(key, operand);
4474 __ RecordWrite(elements, 4539 __ RecordWrite(elements,
4475 key, 4540 key,
4476 value, 4541 value,
4477 GetSaveFPRegsMode(), 4542 GetSaveFPRegsMode(),
(...skipping 2071 matching lines...) Expand 10 before | Expand all | Expand 10 after
6549 FixedArray::kHeaderSize - kPointerSize)); 6614 FixedArray::kHeaderSize - kPointerSize));
6550 __ bind(&done); 6615 __ bind(&done);
6551 } 6616 }
6552 6617
6553 6618
6554 #undef __ 6619 #undef __
6555 6620
6556 } } // namespace v8::internal 6621 } } // namespace v8::internal
6557 6622
6558 #endif // V8_TARGET_ARCH_IA32 6623 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698