| 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 |