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

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

Issue 179773002: [x64] Improve key value sign-extension of dehoisted LoadKeyed/StoreKeyed (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: address comments and add testcase Created 6 years, 9 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
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-gap-resolver-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 osr_pc_offset_ = masm()->pc_offset(); 266 osr_pc_offset_ = masm()->pc_offset();
267 267
268 // Adjust the frame size, subsuming the unoptimized frame into the 268 // Adjust the frame size, subsuming the unoptimized frame into the
269 // optimized frame. 269 // optimized frame.
270 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 270 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
271 ASSERT(slots >= 0); 271 ASSERT(slots >= 0);
272 __ subq(rsp, Immediate(slots * kPointerSize)); 272 __ subq(rsp, Immediate(slots * kPointerSize));
273 } 273 }
274 274
275 275
276 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
277 if (instr->HasResult() && instr->MustSignExtendResult(chunk())) {
278 Register result_reg = ToRegister(instr->result());
279 __ movsxlq(result_reg, result_reg);
danno 2014/03/19 09:16:43 I think it is possible for results to be allocated
Weiliang 2014/03/19 11:41:04 Done.
280 }
281 }
282
283
276 bool LCodeGen::GenerateJumpTable() { 284 bool LCodeGen::GenerateJumpTable() {
277 Label needs_frame; 285 Label needs_frame;
278 if (jump_table_.length() > 0) { 286 if (jump_table_.length() > 0) {
279 Comment(";;; -------------------- Jump table --------------------"); 287 Comment(";;; -------------------- Jump table --------------------");
280 } 288 }
281 for (int i = 0; i < jump_table_.length(); i++) { 289 for (int i = 0; i < jump_table_.length(); i++) {
282 __ bind(&jump_table_[i].label); 290 __ bind(&jump_table_[i].label);
283 Address entry = jump_table_[i].address; 291 Address entry = jump_table_[i].address;
284 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; 292 Deoptimizer::BailoutType type = jump_table_[i].bailout_type;
285 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 293 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 return ToDoubleRegister(op->index()); 405 return ToDoubleRegister(op->index());
398 } 406 }
399 407
400 408
401 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { 409 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const {
402 return op->IsConstantOperand() && 410 return op->IsConstantOperand() &&
403 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); 411 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
404 } 412 }
405 413
406 414
415 bool LCodeGen::IsDehoistedKeyConstant(LConstantOperand* op) const {
416 return op->IsConstantOperand() &&
417 chunk_->IsDehoistedKey(chunk_->LookupConstant(op));
418 }
419
420
407 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { 421 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const {
408 return op->IsConstantOperand() && 422 return op->IsConstantOperand() &&
409 chunk_->LookupLiteralRepresentation(op).IsSmi(); 423 chunk_->LookupLiteralRepresentation(op).IsSmi();
410 } 424 }
411 425
412 426
413 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { 427 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const {
414 return op->IsConstantOperand() && 428 return op->IsConstantOperand() &&
415 chunk_->LookupLiteralRepresentation(op).IsTagged(); 429 chunk_->LookupLiteralRepresentation(op).IsTagged();
416 } 430 }
(...skipping 2444 matching lines...) Expand 10 before | Expand all | Expand 10 after
2861 StackArgumentsAccessor args(arguments, length, 2875 StackArgumentsAccessor args(arguments, length,
2862 ARGUMENTS_DONT_CONTAIN_RECEIVER); 2876 ARGUMENTS_DONT_CONTAIN_RECEIVER);
2863 __ movp(result, args.GetArgumentOperand(0)); 2877 __ movp(result, args.GetArgumentOperand(0));
2864 } 2878 }
2865 } 2879 }
2866 2880
2867 2881
2868 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 2882 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2869 ElementsKind elements_kind = instr->elements_kind(); 2883 ElementsKind elements_kind = instr->elements_kind();
2870 LOperand* key = instr->key(); 2884 LOperand* key = instr->key();
2871 if (!key->IsConstantOperand()) {
2872 Register key_reg = ToRegister(key);
2873 // Even though the HLoad/StoreKeyed (in this case) instructions force
2874 // the input representation for the key to be an integer, the input
2875 // gets replaced during bound check elimination with the index argument
2876 // to the bounds check, which can be tagged, so that case must be
2877 // handled here, too.
2878 if (instr->hydrogen()->IsDehoisted()) {
2879 // Sign extend key because it could be a 32 bit negative value
2880 // and the dehoisted address computation happens in 64 bits
2881 __ movsxlq(key_reg, key_reg);
2882 }
2883 }
2884 int base_offset = instr->is_fixed_typed_array() 2885 int base_offset = instr->is_fixed_typed_array()
2885 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 2886 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
2886 : 0; 2887 : 0;
2887 Operand operand(BuildFastArrayOperand( 2888 Operand operand(BuildFastArrayOperand(
2888 instr->elements(), 2889 instr->elements(),
2889 key, 2890 key,
2890 elements_kind, 2891 elements_kind,
2891 base_offset, 2892 base_offset,
2892 instr->additional_index())); 2893 instr->additional_index()));
2893 2894
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2947 UNREACHABLE(); 2948 UNREACHABLE();
2948 break; 2949 break;
2949 } 2950 }
2950 } 2951 }
2951 } 2952 }
2952 2953
2953 2954
2954 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 2955 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2955 XMMRegister result(ToDoubleRegister(instr->result())); 2956 XMMRegister result(ToDoubleRegister(instr->result()));
2956 LOperand* key = instr->key(); 2957 LOperand* key = instr->key();
2957 if (!key->IsConstantOperand()) {
2958 Register key_reg = ToRegister(key);
2959 // Even though the HLoad/StoreKeyed instructions force the input
2960 // representation for the key to be an integer, the input gets replaced
2961 // during bound check elimination with the index argument to the bounds
2962 // check, which can be tagged, so that case must be handled here, too.
2963 if (instr->hydrogen()->IsDehoisted()) {
2964 // Sign extend key because it could be a 32 bit negative value
2965 // and the dehoisted address computation happens in 64 bits
2966 __ movsxlq(key_reg, key_reg);
2967 }
2968 }
2969
2970 if (instr->hydrogen()->RequiresHoleCheck()) { 2958 if (instr->hydrogen()->RequiresHoleCheck()) {
2971 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2959 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2972 sizeof(kHoleNanLower32); 2960 sizeof(kHoleNanLower32);
2973 Operand hole_check_operand = BuildFastArrayOperand( 2961 Operand hole_check_operand = BuildFastArrayOperand(
2974 instr->elements(), 2962 instr->elements(),
2975 key, 2963 key,
2976 FAST_DOUBLE_ELEMENTS, 2964 FAST_DOUBLE_ELEMENTS,
2977 offset, 2965 offset,
2978 instr->additional_index()); 2966 instr->additional_index());
2979 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 2967 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2980 DeoptimizeIf(equal, instr->environment()); 2968 DeoptimizeIf(equal, instr->environment());
2981 } 2969 }
2982 2970
2983 Operand double_load_operand = BuildFastArrayOperand( 2971 Operand double_load_operand = BuildFastArrayOperand(
2984 instr->elements(), 2972 instr->elements(),
2985 key, 2973 key,
2986 FAST_DOUBLE_ELEMENTS, 2974 FAST_DOUBLE_ELEMENTS,
2987 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 2975 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2988 instr->additional_index()); 2976 instr->additional_index());
2989 __ movsd(result, double_load_operand); 2977 __ movsd(result, double_load_operand);
2990 } 2978 }
2991 2979
2992 2980
2993 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 2981 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
2994 HLoadKeyed* hinstr = instr->hydrogen(); 2982 HLoadKeyed* hinstr = instr->hydrogen();
2995 Register result = ToRegister(instr->result()); 2983 Register result = ToRegister(instr->result());
2996 LOperand* key = instr->key(); 2984 LOperand* key = instr->key();
2997 if (!key->IsConstantOperand()) {
2998 Register key_reg = ToRegister(key);
2999 // Even though the HLoad/StoreKeyedFastElement instructions force
3000 // the input representation for the key to be an integer, the input
3001 // gets replaced during bound check elimination with the index
3002 // argument to the bounds check, which can be tagged, so that
3003 // case must be handled here, too.
3004 if (hinstr->IsDehoisted()) {
3005 // Sign extend key because it could be a 32 bit negative value
3006 // and the dehoisted address computation happens in 64 bits
3007 __ movsxlq(key_reg, key_reg);
3008 }
3009 }
3010
3011 bool requires_hole_check = hinstr->RequiresHoleCheck(); 2985 bool requires_hole_check = hinstr->RequiresHoleCheck();
3012 int offset = FixedArray::kHeaderSize - kHeapObjectTag; 2986 int offset = FixedArray::kHeaderSize - kHeapObjectTag;
3013 Representation representation = hinstr->representation(); 2987 Representation representation = hinstr->representation();
3014 2988
3015 if (representation.IsInteger32() && 2989 if (representation.IsInteger32() &&
3016 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { 2990 hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
3017 ASSERT(!requires_hole_check); 2991 ASSERT(!requires_hole_check);
3018 #ifdef DEBUG 2992 #ifdef DEBUG
3019 Register scratch = kScratchRegister; 2993 Register scratch = kScratchRegister;
3020 __ Load(scratch, 2994 __ Load(scratch,
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after
4032 if (instr->index()->IsConstantOperand()) { 4006 if (instr->index()->IsConstantOperand()) {
4033 int32_t constant_index = 4007 int32_t constant_index =
4034 ToInteger32(LConstantOperand::cast(instr->index())); 4008 ToInteger32(LConstantOperand::cast(instr->index()));
4035 if (instr->hydrogen()->length()->representation().IsSmi()) { 4009 if (instr->hydrogen()->length()->representation().IsSmi()) {
4036 __ Cmp(reg, Smi::FromInt(constant_index)); 4010 __ Cmp(reg, Smi::FromInt(constant_index));
4037 } else { 4011 } else {
4038 __ cmpq(reg, Immediate(constant_index)); 4012 __ cmpq(reg, Immediate(constant_index));
4039 } 4013 }
4040 } else { 4014 } else {
4041 Register reg2 = ToRegister(instr->index()); 4015 Register reg2 = ToRegister(instr->index());
4042 if (!instr->hydrogen()->index()->representation().IsSmi()) { 4016 if (!instr->hydrogen()->index()->representation().IsSmi() &&
4017 !chunk()->IsDehoistedKey(instr->hydrogen()->index())) {
4043 __ AssertZeroExtended(reg2); 4018 __ AssertZeroExtended(reg2);
4044 } 4019 }
4045 __ cmpq(reg, reg2); 4020 __ cmpq(reg, reg2);
4046 } 4021 }
4047 } else { 4022 } else {
4048 Operand length = ToOperand(instr->length()); 4023 Operand length = ToOperand(instr->length());
4049 if (instr->index()->IsConstantOperand()) { 4024 if (instr->index()->IsConstantOperand()) {
4050 int32_t constant_index = 4025 int32_t constant_index =
4051 ToInteger32(LConstantOperand::cast(instr->index())); 4026 ToInteger32(LConstantOperand::cast(instr->index()));
4052 if (instr->hydrogen()->length()->representation().IsSmi()) { 4027 if (instr->hydrogen()->length()->representation().IsSmi()) {
4053 __ Cmp(length, Smi::FromInt(constant_index)); 4028 __ Cmp(length, Smi::FromInt(constant_index));
4054 } else { 4029 } else {
4055 __ cmpq(length, Immediate(constant_index)); 4030 __ cmpq(length, Immediate(constant_index));
4056 } 4031 }
4057 } else { 4032 } else {
4058 __ cmpq(length, ToRegister(instr->index())); 4033 __ cmpq(length, ToRegister(instr->index()));
4059 } 4034 }
4060 } 4035 }
4061 Condition condition = 4036 Condition condition =
4062 instr->hydrogen()->allow_equality() ? below : below_equal; 4037 instr->hydrogen()->allow_equality() ? below : below_equal;
4063 ApplyCheckIf(condition, instr); 4038 ApplyCheckIf(condition, instr);
4064 } 4039 }
4065 4040
4066 4041
4067 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4042 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4068 ElementsKind elements_kind = instr->elements_kind(); 4043 ElementsKind elements_kind = instr->elements_kind();
4069 LOperand* key = instr->key(); 4044 LOperand* key = instr->key();
4070 if (!key->IsConstantOperand()) {
4071 Register key_reg = ToRegister(key);
4072 // Even though the HLoad/StoreKeyedFastElement instructions force
4073 // the input representation for the key to be an integer, the input
4074 // gets replaced during bound check elimination with the index
4075 // argument to the bounds check, which can be tagged, so that case
4076 // must be handled here, too.
4077 if (instr->hydrogen()->IsDehoisted()) {
4078 // Sign extend key because it could be a 32 bit negative value
4079 // and the dehoisted address computation happens in 64 bits
4080 __ movsxlq(key_reg, key_reg);
4081 }
4082 }
4083 int base_offset = instr->is_fixed_typed_array() 4045 int base_offset = instr->is_fixed_typed_array()
4084 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 4046 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
4085 : 0; 4047 : 0;
4086 Operand operand(BuildFastArrayOperand( 4048 Operand operand(BuildFastArrayOperand(
4087 instr->elements(), 4049 instr->elements(),
4088 key, 4050 key,
4089 elements_kind, 4051 elements_kind,
4090 base_offset, 4052 base_offset,
4091 instr->additional_index())); 4053 instr->additional_index()));
4092 4054
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4136 UNREACHABLE(); 4098 UNREACHABLE();
4137 break; 4099 break;
4138 } 4100 }
4139 } 4101 }
4140 } 4102 }
4141 4103
4142 4104
4143 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4105 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4144 XMMRegister value = ToDoubleRegister(instr->value()); 4106 XMMRegister value = ToDoubleRegister(instr->value());
4145 LOperand* key = instr->key(); 4107 LOperand* key = instr->key();
4146 if (!key->IsConstantOperand()) {
4147 Register key_reg = ToRegister(key);
4148 // Even though the HLoad/StoreKeyedFastElement instructions force
4149 // the input representation for the key to be an integer, the
4150 // input gets replaced during bound check elimination with the index
4151 // argument to the bounds check, which can be tagged, so that case
4152 // must be handled here, too.
4153 if (instr->hydrogen()->IsDehoisted()) {
4154 // Sign extend key because it could be a 32 bit negative value
4155 // and the dehoisted address computation happens in 64 bits
4156 __ movsxlq(key_reg, key_reg);
4157 }
4158 }
4159
4160 if (instr->NeedsCanonicalization()) { 4108 if (instr->NeedsCanonicalization()) {
4161 Label have_value; 4109 Label have_value;
4162 4110
4163 __ ucomisd(value, value); 4111 __ ucomisd(value, value);
4164 __ j(parity_odd, &have_value, Label::kNear); // NaN. 4112 __ j(parity_odd, &have_value, Label::kNear); // NaN.
4165 4113
4166 __ Set(kScratchRegister, BitCast<uint64_t>( 4114 __ Set(kScratchRegister, BitCast<uint64_t>(
4167 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); 4115 FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
4168 __ movq(value, kScratchRegister); 4116 __ movq(value, kScratchRegister);
4169 4117
4170 __ bind(&have_value); 4118 __ bind(&have_value);
4171 } 4119 }
4172 4120
4173 Operand double_store_operand = BuildFastArrayOperand( 4121 Operand double_store_operand = BuildFastArrayOperand(
4174 instr->elements(), 4122 instr->elements(),
4175 key, 4123 key,
4176 FAST_DOUBLE_ELEMENTS, 4124 FAST_DOUBLE_ELEMENTS,
4177 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 4125 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
4178 instr->additional_index()); 4126 instr->additional_index());
4179 4127
4180 __ movsd(double_store_operand, value); 4128 __ movsd(double_store_operand, value);
4181 } 4129 }
4182 4130
4183 4131
4184 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4132 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4185 HStoreKeyed* hinstr = instr->hydrogen(); 4133 HStoreKeyed* hinstr = instr->hydrogen();
4186 LOperand* key = instr->key(); 4134 LOperand* key = instr->key();
4187 if (!key->IsConstantOperand()) {
4188 Register key_reg = ToRegister(key);
4189 // Even though the HLoad/StoreKeyedFastElement instructions force
4190 // the input representation for the key to be an integer, the
4191 // input gets replaced during bound check elimination with the index
4192 // argument to the bounds check, which can be tagged, so that case
4193 // must be handled here, too.
4194 if (hinstr->IsDehoisted()) {
4195 // Sign extend key because it could be a 32 bit negative value
4196 // and the dehoisted address computation happens in 64 bits
4197 __ movsxlq(key_reg, key_reg);
4198 }
4199 }
4200
4201 int offset = FixedArray::kHeaderSize - kHeapObjectTag; 4135 int offset = FixedArray::kHeaderSize - kHeapObjectTag;
4202 Representation representation = hinstr->value()->representation(); 4136 Representation representation = hinstr->value()->representation();
4203 4137
4204 if (representation.IsInteger32()) { 4138 if (representation.IsInteger32()) {
4205 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 4139 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
4206 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); 4140 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
4207 #ifdef DEBUG 4141 #ifdef DEBUG
4208 Register scratch = kScratchRegister; 4142 Register scratch = kScratchRegister;
4209 __ Load(scratch, 4143 __ Load(scratch,
4210 BuildFastArrayOperand(instr->elements(), 4144 BuildFastArrayOperand(instr->elements(),
(...skipping 1367 matching lines...) Expand 10 before | Expand all | Expand 10 after
5578 FixedArray::kHeaderSize - kPointerSize)); 5512 FixedArray::kHeaderSize - kPointerSize));
5579 __ bind(&done); 5513 __ bind(&done);
5580 } 5514 }
5581 5515
5582 5516
5583 #undef __ 5517 #undef __
5584 5518
5585 } } // namespace v8::internal 5519 } } // namespace v8::internal
5586 5520
5587 #endif // V8_TARGET_ARCH_X64 5521 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-gap-resolver-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698