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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |