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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |