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

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: support result in the stack slot 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
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 if (instr->result()->IsRegister()) {
279 Register result_reg = ToRegister(instr->result());
280 __ movsxlq(result_reg, result_reg);
281 } else {
282 // sign extend the 32bit in the stack slots
283 ASSERT(instr->result()->IsStackSlot());
284 Operand src = ToOperand(instr->result());
285 __ movsxlq(kScratchRegister, src);
286 __ movq(src, kScratchRegister);
287 }
288 }
289 }
290
291
276 bool LCodeGen::GenerateJumpTable() { 292 bool LCodeGen::GenerateJumpTable() {
277 Label needs_frame; 293 Label needs_frame;
278 if (jump_table_.length() > 0) { 294 if (jump_table_.length() > 0) {
279 Comment(";;; -------------------- Jump table --------------------"); 295 Comment(";;; -------------------- Jump table --------------------");
280 } 296 }
281 for (int i = 0; i < jump_table_.length(); i++) { 297 for (int i = 0; i < jump_table_.length(); i++) {
282 __ bind(&jump_table_[i].label); 298 __ bind(&jump_table_[i].label);
283 Address entry = jump_table_[i].address; 299 Address entry = jump_table_[i].address;
284 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; 300 Deoptimizer::BailoutType type = jump_table_[i].bailout_type;
285 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); 301 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 return ToDoubleRegister(op->index()); 413 return ToDoubleRegister(op->index());
398 } 414 }
399 415
400 416
401 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { 417 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const {
402 return op->IsConstantOperand() && 418 return op->IsConstantOperand() &&
403 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); 419 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
404 } 420 }
405 421
406 422
423 bool LCodeGen::IsDehoistedKeyConstant(LConstantOperand* op) const {
424 return op->IsConstantOperand() &&
425 chunk_->IsDehoistedKey(chunk_->LookupConstant(op));
426 }
427
428
407 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { 429 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const {
408 return op->IsConstantOperand() && 430 return op->IsConstantOperand() &&
409 chunk_->LookupLiteralRepresentation(op).IsSmi(); 431 chunk_->LookupLiteralRepresentation(op).IsSmi();
410 } 432 }
411 433
412 434
413 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { 435 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const {
414 return op->IsConstantOperand() && 436 return op->IsConstantOperand() &&
415 chunk_->LookupLiteralRepresentation(op).IsTagged(); 437 chunk_->LookupLiteralRepresentation(op).IsTagged();
416 } 438 }
(...skipping 2444 matching lines...) Expand 10 before | Expand all | Expand 10 after
2861 StackArgumentsAccessor args(arguments, length, 2883 StackArgumentsAccessor args(arguments, length,
2862 ARGUMENTS_DONT_CONTAIN_RECEIVER); 2884 ARGUMENTS_DONT_CONTAIN_RECEIVER);
2863 __ movp(result, args.GetArgumentOperand(0)); 2885 __ movp(result, args.GetArgumentOperand(0));
2864 } 2886 }
2865 } 2887 }
2866 2888
2867 2889
2868 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 2890 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
2869 ElementsKind elements_kind = instr->elements_kind(); 2891 ElementsKind elements_kind = instr->elements_kind();
2870 LOperand* key = instr->key(); 2892 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() 2893 int base_offset = instr->is_fixed_typed_array()
2885 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 2894 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
2886 : 0; 2895 : 0;
2887 Operand operand(BuildFastArrayOperand( 2896 Operand operand(BuildFastArrayOperand(
2888 instr->elements(), 2897 instr->elements(),
2889 key, 2898 key,
2890 elements_kind, 2899 elements_kind,
2891 base_offset, 2900 base_offset,
2892 instr->additional_index())); 2901 instr->additional_index()));
2893 2902
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2947 UNREACHABLE(); 2956 UNREACHABLE();
2948 break; 2957 break;
2949 } 2958 }
2950 } 2959 }
2951 } 2960 }
2952 2961
2953 2962
2954 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 2963 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
2955 XMMRegister result(ToDoubleRegister(instr->result())); 2964 XMMRegister result(ToDoubleRegister(instr->result()));
2956 LOperand* key = instr->key(); 2965 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()) { 2966 if (instr->hydrogen()->RequiresHoleCheck()) {
2971 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2967 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2972 sizeof(kHoleNanLower32); 2968 sizeof(kHoleNanLower32);
2973 Operand hole_check_operand = BuildFastArrayOperand( 2969 Operand hole_check_operand = BuildFastArrayOperand(
2974 instr->elements(), 2970 instr->elements(),
2975 key, 2971 key,
2976 FAST_DOUBLE_ELEMENTS, 2972 FAST_DOUBLE_ELEMENTS,
2977 offset, 2973 offset,
2978 instr->additional_index()); 2974 instr->additional_index());
2979 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 2975 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2980 DeoptimizeIf(equal, instr->environment()); 2976 DeoptimizeIf(equal, instr->environment());
2981 } 2977 }
2982 2978
2983 Operand double_load_operand = BuildFastArrayOperand( 2979 Operand double_load_operand = BuildFastArrayOperand(
2984 instr->elements(), 2980 instr->elements(),
2985 key, 2981 key,
2986 FAST_DOUBLE_ELEMENTS, 2982 FAST_DOUBLE_ELEMENTS,
2987 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 2983 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2988 instr->additional_index()); 2984 instr->additional_index());
2989 __ movsd(result, double_load_operand); 2985 __ movsd(result, double_load_operand);
2990 } 2986 }
2991 2987
2992 2988
2993 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 2989 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
2994 HLoadKeyed* hinstr = instr->hydrogen(); 2990 HLoadKeyed* hinstr = instr->hydrogen();
2995 Register result = ToRegister(instr->result()); 2991 Register result = ToRegister(instr->result());
2996 LOperand* key = instr->key(); 2992 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(); 2993 bool requires_hole_check = hinstr->RequiresHoleCheck();
3012 int offset = FixedArray::kHeaderSize - kHeapObjectTag; 2994 int offset = FixedArray::kHeaderSize - kHeapObjectTag;
3013 Representation representation = hinstr->representation(); 2995 Representation representation = hinstr->representation();
3014 2996
3015 if (representation.IsInteger32() && 2997 if (representation.IsInteger32() &&
3016 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { 2998 hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
3017 ASSERT(!requires_hole_check); 2999 ASSERT(!requires_hole_check);
3018 #ifdef DEBUG 3000 #ifdef DEBUG
3019 Register scratch = kScratchRegister; 3001 Register scratch = kScratchRegister;
3020 __ Load(scratch, 3002 __ Load(scratch,
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after
4032 if (instr->index()->IsConstantOperand()) { 4014 if (instr->index()->IsConstantOperand()) {
4033 int32_t constant_index = 4015 int32_t constant_index =
4034 ToInteger32(LConstantOperand::cast(instr->index())); 4016 ToInteger32(LConstantOperand::cast(instr->index()));
4035 if (instr->hydrogen()->length()->representation().IsSmi()) { 4017 if (instr->hydrogen()->length()->representation().IsSmi()) {
4036 __ Cmp(reg, Smi::FromInt(constant_index)); 4018 __ Cmp(reg, Smi::FromInt(constant_index));
4037 } else { 4019 } else {
4038 __ cmpq(reg, Immediate(constant_index)); 4020 __ cmpq(reg, Immediate(constant_index));
4039 } 4021 }
4040 } else { 4022 } else {
4041 Register reg2 = ToRegister(instr->index()); 4023 Register reg2 = ToRegister(instr->index());
4042 if (!instr->hydrogen()->index()->representation().IsSmi()) { 4024 if (!instr->hydrogen()->index()->representation().IsSmi() &&
4025 !chunk()->IsDehoistedKey(instr->hydrogen()->index())) {
4043 __ AssertZeroExtended(reg2); 4026 __ AssertZeroExtended(reg2);
4044 } 4027 }
4045 __ cmpq(reg, reg2); 4028 __ cmpq(reg, reg2);
4046 } 4029 }
4047 } else { 4030 } else {
4048 Operand length = ToOperand(instr->length()); 4031 Operand length = ToOperand(instr->length());
4049 if (instr->index()->IsConstantOperand()) { 4032 if (instr->index()->IsConstantOperand()) {
4050 int32_t constant_index = 4033 int32_t constant_index =
4051 ToInteger32(LConstantOperand::cast(instr->index())); 4034 ToInteger32(LConstantOperand::cast(instr->index()));
4052 if (instr->hydrogen()->length()->representation().IsSmi()) { 4035 if (instr->hydrogen()->length()->representation().IsSmi()) {
4053 __ Cmp(length, Smi::FromInt(constant_index)); 4036 __ Cmp(length, Smi::FromInt(constant_index));
4054 } else { 4037 } else {
4055 __ cmpq(length, Immediate(constant_index)); 4038 __ cmpq(length, Immediate(constant_index));
4056 } 4039 }
4057 } else { 4040 } else {
4058 __ cmpq(length, ToRegister(instr->index())); 4041 __ cmpq(length, ToRegister(instr->index()));
4059 } 4042 }
4060 } 4043 }
4061 Condition condition = 4044 Condition condition =
4062 instr->hydrogen()->allow_equality() ? below : below_equal; 4045 instr->hydrogen()->allow_equality() ? below : below_equal;
4063 ApplyCheckIf(condition, instr); 4046 ApplyCheckIf(condition, instr);
4064 } 4047 }
4065 4048
4066 4049
4067 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4050 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4068 ElementsKind elements_kind = instr->elements_kind(); 4051 ElementsKind elements_kind = instr->elements_kind();
4069 LOperand* key = instr->key(); 4052 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() 4053 int base_offset = instr->is_fixed_typed_array()
4084 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag 4054 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
4085 : 0; 4055 : 0;
4086 Operand operand(BuildFastArrayOperand( 4056 Operand operand(BuildFastArrayOperand(
4087 instr->elements(), 4057 instr->elements(),
4088 key, 4058 key,
4089 elements_kind, 4059 elements_kind,
4090 base_offset, 4060 base_offset,
4091 instr->additional_index())); 4061 instr->additional_index()));
4092 4062
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4136 UNREACHABLE(); 4106 UNREACHABLE();
4137 break; 4107 break;
4138 } 4108 }
4139 } 4109 }
4140 } 4110 }
4141 4111
4142 4112
4143 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4113 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4144 XMMRegister value = ToDoubleRegister(instr->value()); 4114 XMMRegister value = ToDoubleRegister(instr->value());
4145 LOperand* key = instr->key(); 4115 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()) { 4116 if (instr->NeedsCanonicalization()) {
4161 Label have_value; 4117 Label have_value;
4162 4118
4163 __ ucomisd(value, value); 4119 __ ucomisd(value, value);
4164 __ j(parity_odd, &have_value, Label::kNear); // NaN. 4120 __ j(parity_odd, &have_value, Label::kNear); // NaN.
4165 4121
4166 __ Set(kScratchRegister, BitCast<uint64_t>( 4122 __ Set(kScratchRegister, BitCast<uint64_t>(
4167 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); 4123 FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
4168 __ movq(value, kScratchRegister); 4124 __ movq(value, kScratchRegister);
4169 4125
4170 __ bind(&have_value); 4126 __ bind(&have_value);
4171 } 4127 }
4172 4128
4173 Operand double_store_operand = BuildFastArrayOperand( 4129 Operand double_store_operand = BuildFastArrayOperand(
4174 instr->elements(), 4130 instr->elements(),
4175 key, 4131 key,
4176 FAST_DOUBLE_ELEMENTS, 4132 FAST_DOUBLE_ELEMENTS,
4177 FixedDoubleArray::kHeaderSize - kHeapObjectTag, 4133 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
4178 instr->additional_index()); 4134 instr->additional_index());
4179 4135
4180 __ movsd(double_store_operand, value); 4136 __ movsd(double_store_operand, value);
4181 } 4137 }
4182 4138
4183 4139
4184 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4140 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4185 HStoreKeyed* hinstr = instr->hydrogen(); 4141 HStoreKeyed* hinstr = instr->hydrogen();
4186 LOperand* key = instr->key(); 4142 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; 4143 int offset = FixedArray::kHeaderSize - kHeapObjectTag;
4202 Representation representation = hinstr->value()->representation(); 4144 Representation representation = hinstr->value()->representation();
4203 4145
4204 if (representation.IsInteger32()) { 4146 if (representation.IsInteger32()) {
4205 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); 4147 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
4206 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); 4148 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
4207 #ifdef DEBUG 4149 #ifdef DEBUG
4208 Register scratch = kScratchRegister; 4150 Register scratch = kScratchRegister;
4209 __ Load(scratch, 4151 __ Load(scratch,
4210 BuildFastArrayOperand(instr->elements(), 4152 BuildFastArrayOperand(instr->elements(),
(...skipping 1367 matching lines...) Expand 10 before | Expand all | Expand 10 after
5578 FixedArray::kHeaderSize - kPointerSize)); 5520 FixedArray::kHeaderSize - kPointerSize));
5579 __ bind(&done); 5521 __ bind(&done);
5580 } 5522 }
5581 5523
5582 5524
5583 #undef __ 5525 #undef __
5584 5526
5585 } } // namespace v8::internal 5527 } } // namespace v8::internal
5586 5528
5587 #endif // V8_TARGET_ARCH_X64 5529 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698