OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/crankshaft/hydrogen-instructions.h" | 5 #include "src/crankshaft/hydrogen-instructions.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/safe_math.h" | 8 #include "src/base/safe_math.h" |
9 #include "src/crankshaft/hydrogen-infer-representation.h" | 9 #include "src/crankshaft/hydrogen-infer-representation.h" |
10 #include "src/double.h" | 10 #include "src/double.h" |
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1418 HValue* arg; | 1418 HValue* arg; |
1419 if (MatchDoubleNegation(this, &arg) && !arg->CheckFlag(kUint32)) { | 1419 if (MatchDoubleNegation(this, &arg) && !arg->CheckFlag(kUint32)) { |
1420 return arg; | 1420 return arg; |
1421 } | 1421 } |
1422 return this; | 1422 return this; |
1423 } | 1423 } |
1424 | 1424 |
1425 | 1425 |
1426 // static | 1426 // static |
1427 HInstruction* HAdd::New(Isolate* isolate, Zone* zone, HValue* context, | 1427 HInstruction* HAdd::New(Isolate* isolate, Zone* zone, HValue* context, |
1428 HValue* left, HValue* right, Strength strength, | 1428 HValue* left, HValue* right, |
1429 ExternalAddType external_add_type) { | 1429 ExternalAddType external_add_type) { |
1430 // For everything else, you should use the other factory method without | 1430 // For everything else, you should use the other factory method without |
1431 // ExternalAddType. | 1431 // ExternalAddType. |
1432 DCHECK_EQ(external_add_type, AddOfExternalAndTagged); | 1432 DCHECK_EQ(external_add_type, AddOfExternalAndTagged); |
1433 return new (zone) HAdd(context, left, right, strength, external_add_type); | 1433 return new (zone) HAdd(context, left, right, external_add_type); |
1434 } | 1434 } |
1435 | 1435 |
1436 | 1436 |
1437 Representation HAdd::RepresentationFromInputs() { | 1437 Representation HAdd::RepresentationFromInputs() { |
1438 Representation left_rep = left()->representation(); | 1438 Representation left_rep = left()->representation(); |
1439 if (left_rep.IsExternal()) { | 1439 if (left_rep.IsExternal()) { |
1440 return Representation::External(); | 1440 return Representation::External(); |
1441 } | 1441 } |
1442 return HArithmeticBinaryOperation::RepresentationFromInputs(); | 1442 return HArithmeticBinaryOperation::RepresentationFromInputs(); |
1443 } | 1443 } |
(...skipping 1907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3351 // calling ToPrimitive() on their arguments. The standard Crankshaft | 3351 // calling ToPrimitive() on their arguments. The standard Crankshaft |
3352 // tagged-to-double conversion to ensure the HCompareNumericAndBranch's | 3352 // tagged-to-double conversion to ensure the HCompareNumericAndBranch's |
3353 // inputs are doubles caused 'undefined' to be converted to NaN. That's | 3353 // inputs are doubles caused 'undefined' to be converted to NaN. That's |
3354 // compatible out-of-the box with ordered relational comparisons (<, >, <=, | 3354 // compatible out-of-the box with ordered relational comparisons (<, >, <=, |
3355 // >=). However, for equality comparisons (and for 'in' and 'instanceof'), | 3355 // >=). However, for equality comparisons (and for 'in' and 'instanceof'), |
3356 // it is not consistent with the spec. For example, it would cause undefined | 3356 // it is not consistent with the spec. For example, it would cause undefined |
3357 // == undefined (should be true) to be evaluated as NaN == NaN | 3357 // == undefined (should be true) to be evaluated as NaN == NaN |
3358 // (false). Therefore, any comparisons other than ordered relational | 3358 // (false). Therefore, any comparisons other than ordered relational |
3359 // comparisons must cause a deopt when one of their arguments is undefined. | 3359 // comparisons must cause a deopt when one of their arguments is undefined. |
3360 // See also v8:1434 | 3360 // See also v8:1434 |
3361 if (Token::IsOrderedRelationalCompareOp(token_) && !is_strong(strength())) { | 3361 if (Token::IsOrderedRelationalCompareOp(token_)) { |
3362 SetFlag(kAllowUndefinedAsNaN); | 3362 SetFlag(kAllowUndefinedAsNaN); |
3363 } | 3363 } |
3364 } | 3364 } |
3365 ChangeRepresentation(rep); | 3365 ChangeRepresentation(rep); |
3366 } | 3366 } |
3367 | 3367 |
3368 | 3368 |
3369 std::ostream& HParameter::PrintDataTo(std::ostream& os) const { // NOLINT | 3369 std::ostream& HParameter::PrintDataTo(std::ostream& os) const { // NOLINT |
3370 return os << index(); | 3370 return os << index(); |
3371 } | 3371 } |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3918 return false; | 3918 return false; |
3919 } | 3919 } |
3920 } | 3920 } |
3921 | 3921 |
3922 | 3922 |
3923 #define H_CONSTANT_INT(val) \ | 3923 #define H_CONSTANT_INT(val) \ |
3924 HConstant::New(isolate, zone, context, static_cast<int32_t>(val)) | 3924 HConstant::New(isolate, zone, context, static_cast<int32_t>(val)) |
3925 #define H_CONSTANT_DOUBLE(val) \ | 3925 #define H_CONSTANT_DOUBLE(val) \ |
3926 HConstant::New(isolate, zone, context, static_cast<double>(val)) | 3926 HConstant::New(isolate, zone, context, static_cast<double>(val)) |
3927 | 3927 |
3928 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ | 3928 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ |
3929 HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \ | 3929 HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \ |
3930 HValue* left, HValue* right, Strength strength) { \ | 3930 HValue* left, HValue* right) { \ |
3931 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ | 3931 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ |
3932 HConstant* c_left = HConstant::cast(left); \ | 3932 HConstant* c_left = HConstant::cast(left); \ |
3933 HConstant* c_right = HConstant::cast(right); \ | 3933 HConstant* c_right = HConstant::cast(right); \ |
3934 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ | 3934 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
3935 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ | 3935 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ |
3936 if (IsInt32Double(double_res)) { \ | 3936 if (IsInt32Double(double_res)) { \ |
3937 return H_CONSTANT_INT(double_res); \ | 3937 return H_CONSTANT_INT(double_res); \ |
3938 } \ | 3938 } \ |
3939 return H_CONSTANT_DOUBLE(double_res); \ | 3939 return H_CONSTANT_DOUBLE(double_res); \ |
3940 } \ | 3940 } \ |
3941 } \ | 3941 } \ |
3942 return new (zone) HInstr(context, left, right, strength); \ | 3942 return new (zone) HInstr(context, left, right); \ |
3943 } | 3943 } |
3944 | 3944 |
3945 | |
3946 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) | 3945 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) |
3947 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) | 3946 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) |
3948 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -) | 3947 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -) |
3949 | 3948 |
3950 #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR | 3949 #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR |
3951 | 3950 |
3952 | 3951 |
3953 HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context, | 3952 HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context, |
3954 HValue* left, HValue* right, | 3953 HValue* left, HValue* right, |
3955 PretenureFlag pretenure_flag, | 3954 PretenureFlag pretenure_flag, |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4161 : d_left); | 4160 : d_left); |
4162 } | 4161 } |
4163 } | 4162 } |
4164 // All comparisons failed, must be NaN. | 4163 // All comparisons failed, must be NaN. |
4165 return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN()); | 4164 return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN()); |
4166 } | 4165 } |
4167 } | 4166 } |
4168 return new(zone) HMathMinMax(context, left, right, op); | 4167 return new(zone) HMathMinMax(context, left, right, op); |
4169 } | 4168 } |
4170 | 4169 |
4171 | |
4172 HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context, | 4170 HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context, |
4173 HValue* left, HValue* right, Strength strength) { | 4171 HValue* left, HValue* right) { |
4174 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4172 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4175 HConstant* c_left = HConstant::cast(left); | 4173 HConstant* c_left = HConstant::cast(left); |
4176 HConstant* c_right = HConstant::cast(right); | 4174 HConstant* c_right = HConstant::cast(right); |
4177 if (c_left->HasInteger32Value() && c_right->HasInteger32Value()) { | 4175 if (c_left->HasInteger32Value() && c_right->HasInteger32Value()) { |
4178 int32_t dividend = c_left->Integer32Value(); | 4176 int32_t dividend = c_left->Integer32Value(); |
4179 int32_t divisor = c_right->Integer32Value(); | 4177 int32_t divisor = c_right->Integer32Value(); |
4180 if (dividend == kMinInt && divisor == -1) { | 4178 if (dividend == kMinInt && divisor == -1) { |
4181 return H_CONSTANT_DOUBLE(-0.0); | 4179 return H_CONSTANT_DOUBLE(-0.0); |
4182 } | 4180 } |
4183 if (divisor != 0) { | 4181 if (divisor != 0) { |
4184 int32_t res = dividend % divisor; | 4182 int32_t res = dividend % divisor; |
4185 if ((res == 0) && (dividend < 0)) { | 4183 if ((res == 0) && (dividend < 0)) { |
4186 return H_CONSTANT_DOUBLE(-0.0); | 4184 return H_CONSTANT_DOUBLE(-0.0); |
4187 } | 4185 } |
4188 return H_CONSTANT_INT(res); | 4186 return H_CONSTANT_INT(res); |
4189 } | 4187 } |
4190 } | 4188 } |
4191 } | 4189 } |
4192 return new (zone) HMod(context, left, right, strength); | 4190 return new (zone) HMod(context, left, right); |
4193 } | 4191 } |
4194 | 4192 |
4195 | |
4196 HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context, | 4193 HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context, |
4197 HValue* left, HValue* right, Strength strength) { | 4194 HValue* left, HValue* right) { |
4198 // If left and right are constant values, try to return a constant value. | 4195 // If left and right are constant values, try to return a constant value. |
4199 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4196 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4200 HConstant* c_left = HConstant::cast(left); | 4197 HConstant* c_left = HConstant::cast(left); |
4201 HConstant* c_right = HConstant::cast(right); | 4198 HConstant* c_right = HConstant::cast(right); |
4202 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { | 4199 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
4203 if (c_right->DoubleValue() != 0) { | 4200 if (c_right->DoubleValue() != 0) { |
4204 double double_res = c_left->DoubleValue() / c_right->DoubleValue(); | 4201 double double_res = c_left->DoubleValue() / c_right->DoubleValue(); |
4205 if (IsInt32Double(double_res)) { | 4202 if (IsInt32Double(double_res)) { |
4206 return H_CONSTANT_INT(double_res); | 4203 return H_CONSTANT_INT(double_res); |
4207 } | 4204 } |
4208 return H_CONSTANT_DOUBLE(double_res); | 4205 return H_CONSTANT_DOUBLE(double_res); |
4209 } else { | 4206 } else { |
4210 int sign = Double(c_left->DoubleValue()).Sign() * | 4207 int sign = Double(c_left->DoubleValue()).Sign() * |
4211 Double(c_right->DoubleValue()).Sign(); // Right could be -0. | 4208 Double(c_right->DoubleValue()).Sign(); // Right could be -0. |
4212 return H_CONSTANT_DOUBLE(sign * V8_INFINITY); | 4209 return H_CONSTANT_DOUBLE(sign * V8_INFINITY); |
4213 } | 4210 } |
4214 } | 4211 } |
4215 } | 4212 } |
4216 return new (zone) HDiv(context, left, right, strength); | 4213 return new (zone) HDiv(context, left, right); |
4217 } | 4214 } |
4218 | 4215 |
4219 | |
4220 HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context, | 4216 HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context, |
4221 Token::Value op, HValue* left, HValue* right, | 4217 Token::Value op, HValue* left, HValue* right) { |
4222 Strength strength) { | |
4223 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4218 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4224 HConstant* c_left = HConstant::cast(left); | 4219 HConstant* c_left = HConstant::cast(left); |
4225 HConstant* c_right = HConstant::cast(right); | 4220 HConstant* c_right = HConstant::cast(right); |
4226 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { | 4221 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
4227 int32_t result; | 4222 int32_t result; |
4228 int32_t v_left = c_left->NumberValueAsInteger32(); | 4223 int32_t v_left = c_left->NumberValueAsInteger32(); |
4229 int32_t v_right = c_right->NumberValueAsInteger32(); | 4224 int32_t v_right = c_right->NumberValueAsInteger32(); |
4230 switch (op) { | 4225 switch (op) { |
4231 case Token::BIT_XOR: | 4226 case Token::BIT_XOR: |
4232 result = v_left ^ v_right; | 4227 result = v_left ^ v_right; |
4233 break; | 4228 break; |
4234 case Token::BIT_AND: | 4229 case Token::BIT_AND: |
4235 result = v_left & v_right; | 4230 result = v_left & v_right; |
4236 break; | 4231 break; |
4237 case Token::BIT_OR: | 4232 case Token::BIT_OR: |
4238 result = v_left | v_right; | 4233 result = v_left | v_right; |
4239 break; | 4234 break; |
4240 default: | 4235 default: |
4241 result = 0; // Please the compiler. | 4236 result = 0; // Please the compiler. |
4242 UNREACHABLE(); | 4237 UNREACHABLE(); |
4243 } | 4238 } |
4244 return H_CONSTANT_INT(result); | 4239 return H_CONSTANT_INT(result); |
4245 } | 4240 } |
4246 } | 4241 } |
4247 return new (zone) HBitwise(context, op, left, right, strength); | 4242 return new (zone) HBitwise(context, op, left, right); |
4248 } | 4243 } |
4249 | 4244 |
4250 | 4245 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ |
4251 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ | 4246 HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \ |
4252 HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \ | 4247 HValue* left, HValue* right) { \ |
4253 HValue* left, HValue* right, Strength strength) { \ | 4248 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ |
4254 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ | 4249 HConstant* c_left = HConstant::cast(left); \ |
4255 HConstant* c_left = HConstant::cast(left); \ | 4250 HConstant* c_right = HConstant::cast(right); \ |
4256 HConstant* c_right = HConstant::cast(right); \ | 4251 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
4257 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ | 4252 return H_CONSTANT_INT(result); \ |
4258 return H_CONSTANT_INT(result); \ | 4253 } \ |
4259 } \ | 4254 } \ |
4260 } \ | 4255 return new (zone) HInstr(context, left, right); \ |
4261 return new (zone) HInstr(context, left, right, strength); \ | |
4262 } | 4256 } |
4263 | 4257 |
4264 | |
4265 DEFINE_NEW_H_BITWISE_INSTR(HSar, | 4258 DEFINE_NEW_H_BITWISE_INSTR(HSar, |
4266 c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f)) | 4259 c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f)) |
4267 DEFINE_NEW_H_BITWISE_INSTR(HShl, | 4260 DEFINE_NEW_H_BITWISE_INSTR(HShl, |
4268 c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f)) | 4261 c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f)) |
4269 | 4262 |
4270 #undef DEFINE_NEW_H_BITWISE_INSTR | 4263 #undef DEFINE_NEW_H_BITWISE_INSTR |
4271 | 4264 |
4272 | |
4273 HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context, | 4265 HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context, |
4274 HValue* left, HValue* right, Strength strength) { | 4266 HValue* left, HValue* right) { |
4275 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4267 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4276 HConstant* c_left = HConstant::cast(left); | 4268 HConstant* c_left = HConstant::cast(left); |
4277 HConstant* c_right = HConstant::cast(right); | 4269 HConstant* c_right = HConstant::cast(right); |
4278 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { | 4270 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
4279 int32_t left_val = c_left->NumberValueAsInteger32(); | 4271 int32_t left_val = c_left->NumberValueAsInteger32(); |
4280 int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f; | 4272 int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f; |
4281 if ((right_val == 0) && (left_val < 0)) { | 4273 if ((right_val == 0) && (left_val < 0)) { |
4282 return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val)); | 4274 return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val)); |
4283 } | 4275 } |
4284 return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val); | 4276 return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val); |
4285 } | 4277 } |
4286 } | 4278 } |
4287 return new (zone) HShr(context, left, right, strength); | 4279 return new (zone) HShr(context, left, right); |
4288 } | 4280 } |
4289 | 4281 |
4290 | 4282 |
4291 HInstruction* HSeqStringGetChar::New(Isolate* isolate, Zone* zone, | 4283 HInstruction* HSeqStringGetChar::New(Isolate* isolate, Zone* zone, |
4292 HValue* context, String::Encoding encoding, | 4284 HValue* context, String::Encoding encoding, |
4293 HValue* string, HValue* index) { | 4285 HValue* string, HValue* index) { |
4294 if (FLAG_fold_constants && string->IsConstant() && index->IsConstant()) { | 4286 if (FLAG_fold_constants && string->IsConstant() && index->IsConstant()) { |
4295 HConstant* c_string = HConstant::cast(string); | 4287 HConstant* c_string = HConstant::cast(string); |
4296 HConstant* c_index = HConstant::cast(index); | 4288 HConstant* c_index = HConstant::cast(index); |
4297 if (c_string->HasStringValue() && c_index->HasInteger32Value()) { | 4289 if (c_string->HasStringValue() && c_index->HasInteger32Value()) { |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4663 case HObjectAccess::kExternalMemory: | 4655 case HObjectAccess::kExternalMemory: |
4664 os << "[external-memory]"; | 4656 os << "[external-memory]"; |
4665 break; | 4657 break; |
4666 } | 4658 } |
4667 | 4659 |
4668 return os << "@" << access.offset(); | 4660 return os << "@" << access.offset(); |
4669 } | 4661 } |
4670 | 4662 |
4671 } // namespace internal | 4663 } // namespace internal |
4672 } // namespace v8 | 4664 } // namespace v8 |
OLD | NEW |