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

Side by Side Diff: src/x64/lithium-codegen-x64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 2542 matching lines...) Expand 10 before | Expand all | Expand 10 after
2553 } 2553 }
2554 if (NeedsEagerFrame()) { 2554 if (NeedsEagerFrame()) {
2555 __ movq(rsp, rbp); 2555 __ movq(rsp, rbp);
2556 __ pop(rbp); 2556 __ pop(rbp);
2557 } 2557 }
2558 if (instr->has_constant_parameter_count()) { 2558 if (instr->has_constant_parameter_count()) {
2559 __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize, 2559 __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize,
2560 rcx); 2560 rcx);
2561 } else { 2561 } else {
2562 Register reg = ToRegister(instr->parameter_count()); 2562 Register reg = ToRegister(instr->parameter_count());
2563 __ SmiToInteger32(reg, reg);
2563 Register return_addr_reg = reg.is(rcx) ? rbx : rcx; 2564 Register return_addr_reg = reg.is(rcx) ? rbx : rcx;
2564 __ pop(return_addr_reg); 2565 __ pop(return_addr_reg);
2565 __ shl(reg, Immediate(kPointerSizeLog2)); 2566 __ shl(reg, Immediate(kPointerSizeLog2));
2566 __ addq(rsp, reg); 2567 __ addq(rsp, reg);
2567 __ jmp(return_addr_reg); 2568 __ jmp(return_addr_reg);
2568 } 2569 }
2569 } 2570 }
2570 2571
2571 2572
2572 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2573 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2893 LLoadExternalArrayPointer* instr) { 2894 LLoadExternalArrayPointer* instr) {
2894 Register result = ToRegister(instr->result()); 2895 Register result = ToRegister(instr->result());
2895 Register input = ToRegister(instr->object()); 2896 Register input = ToRegister(instr->object());
2896 __ movq(result, FieldOperand(input, 2897 __ movq(result, FieldOperand(input,
2897 ExternalPixelArray::kExternalPointerOffset)); 2898 ExternalPixelArray::kExternalPointerOffset));
2898 } 2899 }
2899 2900
2900 2901
2901 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { 2902 void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
2902 Register arguments = ToRegister(instr->arguments()); 2903 Register arguments = ToRegister(instr->arguments());
2903 Register length = ToRegister(instr->length());
2904 Register result = ToRegister(instr->result()); 2904 Register result = ToRegister(instr->result());
2905 // There are two words between the frame pointer and the last argument. 2905
2906 // Subtracting from length accounts for one of them add one more. 2906 if (instr->length()->IsConstantOperand() &&
2907 if (instr->index()->IsRegister()) { 2907 instr->index()->IsConstantOperand()) {
2908 __ subl(length, ToRegister(instr->index())); 2908 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
2909 int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
2910 int index = (const_length - const_index) + 1;
2911 __ movq(result, Operand(arguments, index * kPointerSize));
2909 } else { 2912 } else {
2910 __ subl(length, ToOperand(instr->index())); 2913 Register length = ToRegister(instr->length());
2914 // There are two words between the frame pointer and the last argument.
2915 // Subtracting from length accounts for one of them add one more.
2916 if (instr->index()->IsRegister()) {
2917 __ subl(length, ToRegister(instr->index()));
2918 } else {
2919 __ subl(length, ToOperand(instr->index()));
2920 }
2921 __ movq(result,
2922 Operand(arguments, length, times_pointer_size, kPointerSize));
2911 } 2923 }
2912 __ movq(result, Operand(arguments, length, times_pointer_size, kPointerSize));
2913 } 2924 }
2914 2925
2915 2926
2916 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 2927 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2917 ElementsKind elements_kind = instr->elements_kind(); 2928 ElementsKind elements_kind = instr->elements_kind();
2918 LOperand* key = instr->key(); 2929 LOperand* key = instr->key();
2919 if (!key->IsConstantOperand()) { 2930 if (!key->IsConstantOperand()) {
2920 Register key_reg = ToRegister(key); 2931 Register key_reg = ToRegister(key);
2921 // Even though the HLoad/StoreKeyed (in this case) instructions force 2932 // Even though the HLoad/StoreKeyed (in this case) instructions force
2922 // the input representation for the key to be an integer, the input 2933 // the input representation for the key to be an integer, the input
(...skipping 967 matching lines...) Expand 10 before | Expand all | Expand 10 after
3890 } 3901 }
3891 3902
3892 3903
3893 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { 3904 void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
3894 ASSERT(ToRegister(instr->constructor()).is(rdi)); 3905 ASSERT(ToRegister(instr->constructor()).is(rdi));
3895 ASSERT(ToRegister(instr->result()).is(rax)); 3906 ASSERT(ToRegister(instr->result()).is(rax));
3896 ASSERT(FLAG_optimize_constructed_arrays); 3907 ASSERT(FLAG_optimize_constructed_arrays);
3897 3908
3898 __ Set(rax, instr->arity()); 3909 __ Set(rax, instr->arity());
3899 __ Move(rbx, instr->hydrogen()->property_cell()); 3910 __ Move(rbx, instr->hydrogen()->property_cell());
3900 Handle<Code> array_construct_code = 3911 Object* cell_value = instr->hydrogen()->property_cell()->value();
3901 isolate()->builtins()->ArrayConstructCode(); 3912 ElementsKind kind = static_cast<ElementsKind>(Smi::cast(cell_value)->value());
3902 CallCode(array_construct_code, RelocInfo::CONSTRUCT_CALL, instr); 3913 if (instr->arity() == 0) {
3914 ArrayNoArgumentConstructorStub stub(kind);
3915 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3916 } else if (instr->arity() == 1) {
3917 ArraySingleArgumentConstructorStub stub(kind);
3918 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3919 } else {
3920 ArrayNArgumentsConstructorStub stub(kind);
3921 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
3922 }
3903 } 3923 }
3904 3924
3905 3925
3906 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3926 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3907 CallRuntime(instr->function(), instr->arity(), instr); 3927 CallRuntime(instr->function(), instr->arity(), instr);
3908 } 3928 }
3909 3929
3910 3930
3911 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { 3931 void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
3912 Register result = ToRegister(instr->result()); 3932 Register result = ToRegister(instr->result());
3913 Register base = ToRegister(instr->base_object()); 3933 Register base = ToRegister(instr->base_object());
3914 __ lea(result, Operand(base, instr->offset())); 3934 __ lea(result, Operand(base, instr->offset()));
3915 } 3935 }
3916 3936
3917 3937
3918 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 3938 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
3919 Register object = ToRegister(instr->object()); 3939 Register object = ToRegister(instr->object());
3920 Register value = ToRegister(instr->value());
3921 int offset = instr->offset(); 3940 int offset = instr->offset();
3922 3941
3923 if (!instr->transition().is_null()) { 3942 if (!instr->transition().is_null()) {
3924 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { 3943 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) {
3925 __ Move(FieldOperand(object, HeapObject::kMapOffset), 3944 __ Move(FieldOperand(object, HeapObject::kMapOffset),
3926 instr->transition()); 3945 instr->transition());
3927 } else { 3946 } else {
3928 Register temp = ToRegister(instr->temp()); 3947 Register temp = ToRegister(instr->temp());
3929 __ Move(kScratchRegister, instr->transition()); 3948 __ Move(kScratchRegister, instr->transition());
3930 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister); 3949 __ movq(FieldOperand(object, HeapObject::kMapOffset), kScratchRegister);
3931 // Update the write barrier for the map field. 3950 // Update the write barrier for the map field.
3932 __ RecordWriteField(object, 3951 __ RecordWriteField(object,
3933 HeapObject::kMapOffset, 3952 HeapObject::kMapOffset,
3934 kScratchRegister, 3953 kScratchRegister,
3935 temp, 3954 temp,
3936 kSaveFPRegs, 3955 kSaveFPRegs,
3937 OMIT_REMEMBERED_SET, 3956 OMIT_REMEMBERED_SET,
3938 OMIT_SMI_CHECK); 3957 OMIT_SMI_CHECK);
3939 } 3958 }
3940 } 3959 }
3941 3960
3942 // Do the store. 3961 // Do the store.
3943 HType type = instr->hydrogen()->value()->type(); 3962 HType type = instr->hydrogen()->value()->type();
3944 SmiCheck check_needed = 3963 SmiCheck check_needed =
3945 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3964 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3946 if (instr->is_in_object()) { 3965 if (instr->is_in_object()) {
3947 __ movq(FieldOperand(object, offset), value); 3966 if (instr->value()->IsConstantOperand()) {
3967 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
3968 if (IsInteger32Constant(operand_value)) {
3969 int const_value = ToInteger32(operand_value);
3970 __ movq(FieldOperand(object, offset), Immediate(const_value));
3971 } else {
3972 if (operand_value->IsRegister()) {
3973 __ movq(FieldOperand(object, offset), ToRegister(operand_value));
3974 } else {
3975 Handle<Object> handle_value = ToHandle(operand_value);
3976 __ Move(FieldOperand(object, offset), handle_value);
3977 }
3978 }
3979 } else {
3980 __ movq(FieldOperand(object, offset), ToRegister(instr->value()));
3981 }
3982
3948 if (instr->hydrogen()->NeedsWriteBarrier()) { 3983 if (instr->hydrogen()->NeedsWriteBarrier()) {
3984 Register value = ToRegister(instr->value());
3949 Register temp = ToRegister(instr->temp()); 3985 Register temp = ToRegister(instr->temp());
3950 // Update the write barrier for the object for in-object properties. 3986 // Update the write barrier for the object for in-object properties.
3951 __ RecordWriteField(object, 3987 __ RecordWriteField(object,
3952 offset, 3988 offset,
3953 value, 3989 value,
3954 temp, 3990 temp,
3955 kSaveFPRegs, 3991 kSaveFPRegs,
3956 EMIT_REMEMBERED_SET, 3992 EMIT_REMEMBERED_SET,
3957 check_needed); 3993 check_needed);
3958 } 3994 }
3959 } else { 3995 } else {
3960 Register temp = ToRegister(instr->temp()); 3996 Register temp = ToRegister(instr->temp());
3961 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset)); 3997 __ movq(temp, FieldOperand(object, JSObject::kPropertiesOffset));
3962 __ movq(FieldOperand(temp, offset), value); 3998
3999 if (instr->value()->IsConstantOperand()) {
4000 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4001 if (IsInteger32Constant(operand_value)) {
4002 int const_value = ToInteger32(operand_value);
4003 __ movq(FieldOperand(temp, offset), Immediate(const_value));
4004 } else {
4005 if (operand_value->IsRegister()) {
4006 __ movq(FieldOperand(temp, offset), ToRegister(operand_value));
4007 } else {
4008 Handle<Object> handle_value = ToHandle(operand_value);
4009 __ Move(FieldOperand(temp, offset), handle_value);
4010 }
4011 }
4012 } else {
4013 __ movq(FieldOperand(temp, offset), ToRegister(instr->value()));
4014 }
4015
3963 if (instr->hydrogen()->NeedsWriteBarrier()) { 4016 if (instr->hydrogen()->NeedsWriteBarrier()) {
4017 Register value = ToRegister(instr->value());
3964 // Update the write barrier for the properties array. 4018 // Update the write barrier for the properties array.
3965 // object is used as a scratch register. 4019 // object is used as a scratch register.
3966 __ RecordWriteField(temp, 4020 __ RecordWriteField(temp,
3967 offset, 4021 offset,
3968 value, 4022 value,
3969 object, 4023 object,
3970 kSaveFPRegs, 4024 kSaveFPRegs,
3971 EMIT_REMEMBERED_SET, 4025 EMIT_REMEMBERED_SET,
3972 check_needed); 4026 check_needed);
3973 } 4027 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
4129 key, 4183 key,
4130 FAST_DOUBLE_ELEMENTS, 4184 FAST_DOUBLE_ELEMENTS,
4131 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 4185 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
4132 instr->additional_index()); 4186 instr->additional_index());
4133 4187
4134 __ movsd(double_store_operand, value); 4188 __ movsd(double_store_operand, value);
4135 } 4189 }
4136 4190
4137 4191
4138 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4192 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4139 Register value = ToRegister(instr->value());
4140 Register elements = ToRegister(instr->elements()); 4193 Register elements = ToRegister(instr->elements());
4141 LOperand* key = instr->key(); 4194 LOperand* key = instr->key();
4142 if (!key->IsConstantOperand()) { 4195 if (!key->IsConstantOperand()) {
4143 Register key_reg = ToRegister(key); 4196 Register key_reg = ToRegister(key);
4144 // Even though the HLoad/StoreKeyedFastElement instructions force 4197 // Even though the HLoad/StoreKeyedFastElement instructions force
4145 // the input representation for the key to be an integer, the 4198 // the input representation for the key to be an integer, the
4146 // input gets replaced during bound check elimination with the index 4199 // input gets replaced during bound check elimination with the index
4147 // argument to the bounds check, which can be tagged, so that case 4200 // argument to the bounds check, which can be tagged, so that case
4148 // must be handled here, too. 4201 // must be handled here, too.
4149 if (instr->hydrogen()->key()->representation().IsTagged()) { 4202 if (instr->hydrogen()->key()->representation().IsTagged()) {
4150 __ SmiToInteger64(key_reg, key_reg); 4203 __ SmiToInteger64(key_reg, key_reg);
4151 } else if (instr->hydrogen()->IsDehoisted()) { 4204 } else if (instr->hydrogen()->IsDehoisted()) {
4152 // Sign extend key because it could be a 32 bit negative value 4205 // Sign extend key because it could be a 32 bit negative value
4153 // and the dehoisted address computation happens in 64 bits 4206 // and the dehoisted address computation happens in 64 bits
4154 __ movsxlq(key_reg, key_reg); 4207 __ movsxlq(key_reg, key_reg);
4155 } 4208 }
4156 } 4209 }
4157 4210
4158 Operand operand = 4211 Operand operand =
4159 BuildFastArrayOperand(instr->elements(), 4212 BuildFastArrayOperand(instr->elements(),
4160 key, 4213 key,
4161 FAST_ELEMENTS, 4214 FAST_ELEMENTS,
4162 FixedArray::kHeaderSize - kHeapObjectTag, 4215 FixedArray::kHeaderSize - kHeapObjectTag,
4163 instr->additional_index()); 4216 instr->additional_index());
4217 if (instr->value()->IsRegister()) {
4218 __ movq(operand, ToRegister(instr->value()));
4219 } else {
4220 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4221 if (IsInteger32Constant(operand_value)) {
4222 int const_value = ToInteger32(operand_value);
4223 __ movq(operand, Immediate(const_value));
4224 } else {
4225 Handle<Object> handle_value = ToHandle(operand_value);
4226 __ Move(operand, handle_value);
4227 }
4228 }
4164 4229
4165 if (instr->hydrogen()->NeedsWriteBarrier()) { 4230 if (instr->hydrogen()->NeedsWriteBarrier()) {
4231 ASSERT(instr->value()->IsRegister());
4232 Register value = ToRegister(instr->value());
4166 ASSERT(!instr->key()->IsConstantOperand()); 4233 ASSERT(!instr->key()->IsConstantOperand());
4167 HType type = instr->hydrogen()->value()->type(); 4234 HType type = instr->hydrogen()->value()->type();
4168 SmiCheck check_needed = 4235 SmiCheck check_needed =
4169 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4236 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4170 // Compute address of modified element and store it into key register. 4237 // Compute address of modified element and store it into key register.
4171 Register key_reg(ToRegister(key)); 4238 Register key_reg(ToRegister(key));
4172 __ lea(key_reg, operand); 4239 __ lea(key_reg, operand);
4173 __ movq(Operand(key_reg, 0), value); 4240 __ movq(Operand(key_reg, 0), value);
4174 __ RecordWrite(elements, 4241 __ RecordWrite(elements,
4175 key_reg, 4242 key_reg,
4176 value, 4243 value,
4177 kSaveFPRegs, 4244 kSaveFPRegs,
4178 EMIT_REMEMBERED_SET, 4245 EMIT_REMEMBERED_SET,
4179 check_needed); 4246 check_needed);
4180 } else {
4181 __ movq(operand, value);
4182 } 4247 }
4248
4249 // TODO(mvstanton): we don't need this line, do we?
4250 // else {
4251 // __ movq(operand, value);
4252 // }
4183 } 4253 }
4184 4254
4185 4255
4186 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { 4256 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
4187 if (instr->is_external()) { 4257 if (instr->is_external()) {
4188 DoStoreKeyedExternalArray(instr); 4258 DoStoreKeyedExternalArray(instr);
4189 } else if (instr->hydrogen()->value()->representation().IsDouble()) { 4259 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
4190 DoStoreKeyedFixedDoubleArray(instr); 4260 DoStoreKeyedFixedDoubleArray(instr);
4191 } else { 4261 } else {
4192 DoStoreKeyedFixedArray(instr); 4262 DoStoreKeyedFixedArray(instr);
(...skipping 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after
5660 FixedArray::kHeaderSize - kPointerSize)); 5730 FixedArray::kHeaderSize - kPointerSize));
5661 __ bind(&done); 5731 __ bind(&done);
5662 } 5732 }
5663 5733
5664 5734
5665 #undef __ 5735 #undef __
5666 5736
5667 } } // namespace v8::internal 5737 } } // namespace v8::internal
5668 5738
5669 #endif // V8_TARGET_ARCH_X64 5739 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698