| OLD | NEW |
| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { | 276 void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { |
| 277 if (instr->IsCall()) { | 277 if (instr->IsCall()) { |
| 278 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); | 278 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); |
| 279 } | 279 } |
| 280 if (!instr->IsLazyBailout() && !instr->IsGap()) { | 280 if (!instr->IsLazyBailout() && !instr->IsGap()) { |
| 281 safepoints_.BumpLastLazySafepointIndex(); | 281 safepoints_.BumpLastLazySafepointIndex(); |
| 282 } | 282 } |
| 283 } | 283 } |
| 284 | 284 |
| 285 | 285 |
| 286 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { |
| 287 if (instr->HasResult() && instr->MustSignExtendResult(chunk())) { |
| 288 if (instr->result()->IsRegister()) { |
| 289 Register result_reg = ToRegister(instr->result()); |
| 290 __ movsxlq(result_reg, result_reg); |
| 291 } else { |
| 292 // Sign extend the 32bit result in the stack slots. |
| 293 ASSERT(instr->result()->IsStackSlot()); |
| 294 Operand src = ToOperand(instr->result()); |
| 295 __ movsxlq(kScratchRegister, src); |
| 296 __ movq(src, kScratchRegister); |
| 297 } |
| 298 } |
| 299 } |
| 300 |
| 301 |
| 286 bool LCodeGen::GenerateJumpTable() { | 302 bool LCodeGen::GenerateJumpTable() { |
| 287 Label needs_frame; | 303 Label needs_frame; |
| 288 if (jump_table_.length() > 0) { | 304 if (jump_table_.length() > 0) { |
| 289 Comment(";;; -------------------- Jump table --------------------"); | 305 Comment(";;; -------------------- Jump table --------------------"); |
| 290 } | 306 } |
| 291 for (int i = 0; i < jump_table_.length(); i++) { | 307 for (int i = 0; i < jump_table_.length(); i++) { |
| 292 __ bind(&jump_table_[i].label); | 308 __ bind(&jump_table_[i].label); |
| 293 Address entry = jump_table_[i].address; | 309 Address entry = jump_table_[i].address; |
| 294 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; | 310 Deoptimizer::BailoutType type = jump_table_[i].bailout_type; |
| 295 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); | 311 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 return ToDoubleRegister(op->index()); | 423 return ToDoubleRegister(op->index()); |
| 408 } | 424 } |
| 409 | 425 |
| 410 | 426 |
| 411 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { | 427 bool LCodeGen::IsInteger32Constant(LConstantOperand* op) const { |
| 412 return op->IsConstantOperand() && | 428 return op->IsConstantOperand() && |
| 413 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); | 429 chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32(); |
| 414 } | 430 } |
| 415 | 431 |
| 416 | 432 |
| 433 bool LCodeGen::IsDehoistedKeyConstant(LConstantOperand* op) const { |
| 434 return op->IsConstantOperand() && |
| 435 chunk_->IsDehoistedKey(chunk_->LookupConstant(op)); |
| 436 } |
| 437 |
| 438 |
| 417 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { | 439 bool LCodeGen::IsSmiConstant(LConstantOperand* op) const { |
| 418 return op->IsConstantOperand() && | 440 return op->IsConstantOperand() && |
| 419 chunk_->LookupLiteralRepresentation(op).IsSmi(); | 441 chunk_->LookupLiteralRepresentation(op).IsSmi(); |
| 420 } | 442 } |
| 421 | 443 |
| 422 | 444 |
| 423 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { | 445 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { |
| 424 return op->IsConstantOperand() && | 446 return op->IsConstantOperand() && |
| 425 chunk_->LookupLiteralRepresentation(op).IsTagged(); | 447 chunk_->LookupLiteralRepresentation(op).IsTagged(); |
| 426 } | 448 } |
| (...skipping 2506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2933 StackArgumentsAccessor args(arguments, length, | 2955 StackArgumentsAccessor args(arguments, length, |
| 2934 ARGUMENTS_DONT_CONTAIN_RECEIVER); | 2956 ARGUMENTS_DONT_CONTAIN_RECEIVER); |
| 2935 __ movp(result, args.GetArgumentOperand(0)); | 2957 __ movp(result, args.GetArgumentOperand(0)); |
| 2936 } | 2958 } |
| 2937 } | 2959 } |
| 2938 | 2960 |
| 2939 | 2961 |
| 2940 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 2962 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 2941 ElementsKind elements_kind = instr->elements_kind(); | 2963 ElementsKind elements_kind = instr->elements_kind(); |
| 2942 LOperand* key = instr->key(); | 2964 LOperand* key = instr->key(); |
| 2943 if (!key->IsConstantOperand()) { | |
| 2944 Register key_reg = ToRegister(key); | |
| 2945 // Even though the HLoad/StoreKeyed (in this case) instructions force | |
| 2946 // the input representation for the key to be an integer, the input | |
| 2947 // gets replaced during bound check elimination with the index argument | |
| 2948 // to the bounds check, which can be tagged, so that case must be | |
| 2949 // handled here, too. | |
| 2950 if (instr->hydrogen()->IsDehoisted()) { | |
| 2951 // Sign extend key because it could be a 32 bit negative value | |
| 2952 // and the dehoisted address computation happens in 64 bits | |
| 2953 __ movsxlq(key_reg, key_reg); | |
| 2954 } | |
| 2955 } | |
| 2956 int base_offset = instr->is_fixed_typed_array() | 2965 int base_offset = instr->is_fixed_typed_array() |
| 2957 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | 2966 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
| 2958 : 0; | 2967 : 0; |
| 2959 Operand operand(BuildFastArrayOperand( | 2968 Operand operand(BuildFastArrayOperand( |
| 2960 instr->elements(), | 2969 instr->elements(), |
| 2961 key, | 2970 key, |
| 2962 elements_kind, | 2971 elements_kind, |
| 2963 base_offset, | 2972 base_offset, |
| 2964 instr->additional_index())); | 2973 instr->additional_index())); |
| 2965 | 2974 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3019 UNREACHABLE(); | 3028 UNREACHABLE(); |
| 3020 break; | 3029 break; |
| 3021 } | 3030 } |
| 3022 } | 3031 } |
| 3023 } | 3032 } |
| 3024 | 3033 |
| 3025 | 3034 |
| 3026 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3035 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 3027 XMMRegister result(ToDoubleRegister(instr->result())); | 3036 XMMRegister result(ToDoubleRegister(instr->result())); |
| 3028 LOperand* key = instr->key(); | 3037 LOperand* key = instr->key(); |
| 3029 if (!key->IsConstantOperand()) { | |
| 3030 Register key_reg = ToRegister(key); | |
| 3031 // Even though the HLoad/StoreKeyed instructions force the input | |
| 3032 // representation for the key to be an integer, the input gets replaced | |
| 3033 // during bound check elimination with the index argument to the bounds | |
| 3034 // check, which can be tagged, so that case must be handled here, too. | |
| 3035 if (instr->hydrogen()->IsDehoisted()) { | |
| 3036 // Sign extend key because it could be a 32 bit negative value | |
| 3037 // and the dehoisted address computation happens in 64 bits | |
| 3038 __ movsxlq(key_reg, key_reg); | |
| 3039 } | |
| 3040 } | |
| 3041 | |
| 3042 if (instr->hydrogen()->RequiresHoleCheck()) { | 3038 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3043 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 3039 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
| 3044 sizeof(kHoleNanLower32); | 3040 sizeof(kHoleNanLower32); |
| 3045 Operand hole_check_operand = BuildFastArrayOperand( | 3041 Operand hole_check_operand = BuildFastArrayOperand( |
| 3046 instr->elements(), | 3042 instr->elements(), |
| 3047 key, | 3043 key, |
| 3048 FAST_DOUBLE_ELEMENTS, | 3044 FAST_DOUBLE_ELEMENTS, |
| 3049 offset, | 3045 offset, |
| 3050 instr->additional_index()); | 3046 instr->additional_index()); |
| 3051 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); | 3047 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
| 3052 DeoptimizeIf(equal, instr->environment()); | 3048 DeoptimizeIf(equal, instr->environment()); |
| 3053 } | 3049 } |
| 3054 | 3050 |
| 3055 Operand double_load_operand = BuildFastArrayOperand( | 3051 Operand double_load_operand = BuildFastArrayOperand( |
| 3056 instr->elements(), | 3052 instr->elements(), |
| 3057 key, | 3053 key, |
| 3058 FAST_DOUBLE_ELEMENTS, | 3054 FAST_DOUBLE_ELEMENTS, |
| 3059 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3055 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 3060 instr->additional_index()); | 3056 instr->additional_index()); |
| 3061 __ movsd(result, double_load_operand); | 3057 __ movsd(result, double_load_operand); |
| 3062 } | 3058 } |
| 3063 | 3059 |
| 3064 | 3060 |
| 3065 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3061 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3066 HLoadKeyed* hinstr = instr->hydrogen(); | 3062 HLoadKeyed* hinstr = instr->hydrogen(); |
| 3067 Register result = ToRegister(instr->result()); | 3063 Register result = ToRegister(instr->result()); |
| 3068 LOperand* key = instr->key(); | 3064 LOperand* key = instr->key(); |
| 3069 if (!key->IsConstantOperand()) { | |
| 3070 Register key_reg = ToRegister(key); | |
| 3071 // Even though the HLoad/StoreKeyedFastElement instructions force | |
| 3072 // the input representation for the key to be an integer, the input | |
| 3073 // gets replaced during bound check elimination with the index | |
| 3074 // argument to the bounds check, which can be tagged, so that | |
| 3075 // case must be handled here, too. | |
| 3076 if (hinstr->IsDehoisted()) { | |
| 3077 // Sign extend key because it could be a 32 bit negative value | |
| 3078 // and the dehoisted address computation happens in 64 bits | |
| 3079 __ movsxlq(key_reg, key_reg); | |
| 3080 } | |
| 3081 } | |
| 3082 | |
| 3083 bool requires_hole_check = hinstr->RequiresHoleCheck(); | 3065 bool requires_hole_check = hinstr->RequiresHoleCheck(); |
| 3084 int offset = FixedArray::kHeaderSize - kHeapObjectTag; | 3066 int offset = FixedArray::kHeaderSize - kHeapObjectTag; |
| 3085 Representation representation = hinstr->representation(); | 3067 Representation representation = hinstr->representation(); |
| 3086 | 3068 |
| 3087 if (representation.IsInteger32() && | 3069 if (representation.IsInteger32() && |
| 3088 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { | 3070 hinstr->elements_kind() == FAST_SMI_ELEMENTS) { |
| 3089 ASSERT(!requires_hole_check); | 3071 ASSERT(!requires_hole_check); |
| 3090 #ifdef DEBUG | 3072 #ifdef DEBUG |
| 3091 Register scratch = kScratchRegister; | 3073 Register scratch = kScratchRegister; |
| 3092 __ Load(scratch, | 3074 __ Load(scratch, |
| (...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4136 } | 4118 } |
| 4137 } | 4119 } |
| 4138 Condition condition = hinstr->allow_equality() ? below : below_equal; | 4120 Condition condition = hinstr->allow_equality() ? below : below_equal; |
| 4139 ApplyCheckIf(condition, instr); | 4121 ApplyCheckIf(condition, instr); |
| 4140 } | 4122 } |
| 4141 | 4123 |
| 4142 | 4124 |
| 4143 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4125 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 4144 ElementsKind elements_kind = instr->elements_kind(); | 4126 ElementsKind elements_kind = instr->elements_kind(); |
| 4145 LOperand* key = instr->key(); | 4127 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 input | |
| 4150 // 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 int base_offset = instr->is_fixed_typed_array() | 4128 int base_offset = instr->is_fixed_typed_array() |
| 4160 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag | 4129 ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag |
| 4161 : 0; | 4130 : 0; |
| 4162 Operand operand(BuildFastArrayOperand( | 4131 Operand operand(BuildFastArrayOperand( |
| 4163 instr->elements(), | 4132 instr->elements(), |
| 4164 key, | 4133 key, |
| 4165 elements_kind, | 4134 elements_kind, |
| 4166 base_offset, | 4135 base_offset, |
| 4167 instr->additional_index())); | 4136 instr->additional_index())); |
| 4168 | 4137 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4212 UNREACHABLE(); | 4181 UNREACHABLE(); |
| 4213 break; | 4182 break; |
| 4214 } | 4183 } |
| 4215 } | 4184 } |
| 4216 } | 4185 } |
| 4217 | 4186 |
| 4218 | 4187 |
| 4219 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4188 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4220 XMMRegister value = ToDoubleRegister(instr->value()); | 4189 XMMRegister value = ToDoubleRegister(instr->value()); |
| 4221 LOperand* key = instr->key(); | 4190 LOperand* key = instr->key(); |
| 4222 if (!key->IsConstantOperand()) { | |
| 4223 Register key_reg = ToRegister(key); | |
| 4224 // Even though the HLoad/StoreKeyedFastElement instructions force | |
| 4225 // the input representation for the key to be an integer, the | |
| 4226 // input gets replaced during bound check elimination with the index | |
| 4227 // argument to the bounds check, which can be tagged, so that case | |
| 4228 // must be handled here, too. | |
| 4229 if (instr->hydrogen()->IsDehoisted()) { | |
| 4230 // Sign extend key because it could be a 32 bit negative value | |
| 4231 // and the dehoisted address computation happens in 64 bits | |
| 4232 __ movsxlq(key_reg, key_reg); | |
| 4233 } | |
| 4234 } | |
| 4235 | |
| 4236 if (instr->NeedsCanonicalization()) { | 4191 if (instr->NeedsCanonicalization()) { |
| 4237 Label have_value; | 4192 Label have_value; |
| 4238 | 4193 |
| 4239 __ ucomisd(value, value); | 4194 __ ucomisd(value, value); |
| 4240 __ j(parity_odd, &have_value, Label::kNear); // NaN. | 4195 __ j(parity_odd, &have_value, Label::kNear); // NaN. |
| 4241 | 4196 |
| 4242 __ Set(kScratchRegister, BitCast<uint64_t>( | 4197 __ Set(kScratchRegister, BitCast<uint64_t>( |
| 4243 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); | 4198 FixedDoubleArray::canonical_not_the_hole_nan_as_double())); |
| 4244 __ movq(value, kScratchRegister); | 4199 __ movq(value, kScratchRegister); |
| 4245 | 4200 |
| 4246 __ bind(&have_value); | 4201 __ bind(&have_value); |
| 4247 } | 4202 } |
| 4248 | 4203 |
| 4249 Operand double_store_operand = BuildFastArrayOperand( | 4204 Operand double_store_operand = BuildFastArrayOperand( |
| 4250 instr->elements(), | 4205 instr->elements(), |
| 4251 key, | 4206 key, |
| 4252 FAST_DOUBLE_ELEMENTS, | 4207 FAST_DOUBLE_ELEMENTS, |
| 4253 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4208 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
| 4254 instr->additional_index()); | 4209 instr->additional_index()); |
| 4255 | 4210 |
| 4256 __ movsd(double_store_operand, value); | 4211 __ movsd(double_store_operand, value); |
| 4257 } | 4212 } |
| 4258 | 4213 |
| 4259 | 4214 |
| 4260 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4215 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4261 HStoreKeyed* hinstr = instr->hydrogen(); | 4216 HStoreKeyed* hinstr = instr->hydrogen(); |
| 4262 LOperand* key = instr->key(); | 4217 LOperand* key = instr->key(); |
| 4263 if (!key->IsConstantOperand()) { | |
| 4264 Register key_reg = ToRegister(key); | |
| 4265 // Even though the HLoad/StoreKeyedFastElement instructions force | |
| 4266 // the input representation for the key to be an integer, the | |
| 4267 // input gets replaced during bound check elimination with the index | |
| 4268 // argument to the bounds check, which can be tagged, so that case | |
| 4269 // must be handled here, too. | |
| 4270 if (hinstr->IsDehoisted()) { | |
| 4271 // Sign extend key because it could be a 32 bit negative value | |
| 4272 // and the dehoisted address computation happens in 64 bits | |
| 4273 __ movsxlq(key_reg, key_reg); | |
| 4274 } | |
| 4275 } | |
| 4276 | |
| 4277 int offset = FixedArray::kHeaderSize - kHeapObjectTag; | 4218 int offset = FixedArray::kHeaderSize - kHeapObjectTag; |
| 4278 Representation representation = hinstr->value()->representation(); | 4219 Representation representation = hinstr->value()->representation(); |
| 4279 | 4220 |
| 4280 if (representation.IsInteger32()) { | 4221 if (representation.IsInteger32()) { |
| 4281 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 4222 ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
| 4282 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); | 4223 ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS); |
| 4283 #ifdef DEBUG | 4224 #ifdef DEBUG |
| 4284 Register scratch = kScratchRegister; | 4225 Register scratch = kScratchRegister; |
| 4285 __ Load(scratch, | 4226 __ Load(scratch, |
| 4286 BuildFastArrayOperand(instr->elements(), | 4227 BuildFastArrayOperand(instr->elements(), |
| (...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5659 FixedArray::kHeaderSize - kPointerSize)); | 5600 FixedArray::kHeaderSize - kPointerSize)); |
| 5660 __ bind(&done); | 5601 __ bind(&done); |
| 5661 } | 5602 } |
| 5662 | 5603 |
| 5663 | 5604 |
| 5664 #undef __ | 5605 #undef __ |
| 5665 | 5606 |
| 5666 } } // namespace v8::internal | 5607 } } // namespace v8::internal |
| 5667 | 5608 |
| 5668 #endif // V8_TARGET_ARCH_X64 | 5609 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |