| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 11268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11279 if ((left->IsConstant() && | 11279 if ((left->IsConstant() && |
| 11280 HConstant::cast(left)->HasNumberValue()) || | 11280 HConstant::cast(left)->HasNumberValue()) || |
| 11281 (right->IsConstant() && | 11281 (right->IsConstant() && |
| 11282 HConstant::cast(right)->HasNumberValue())) { | 11282 HConstant::cast(right)->HasNumberValue())) { |
| 11283 Add<HDeoptimize>( | 11283 Add<HDeoptimize>( |
| 11284 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, | 11284 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, |
| 11285 Deoptimizer::SOFT); | 11285 Deoptimizer::SOFT); |
| 11286 // The caller expects a branch instruction, so make it happy. | 11286 // The caller expects a branch instruction, so make it happy. |
| 11287 return New<HBranch>(graph()->GetConstantTrue()); | 11287 return New<HBranch>(graph()->GetConstantTrue()); |
| 11288 } | 11288 } |
| 11289 // Can we get away with map check and not instance type check? | 11289 if (op == Token::EQ) { |
| 11290 HValue* operand_to_check = | 11290 // For abstract equality we need to check both sides are receivers. |
| 11291 left->block()->block_id() < right->block()->block_id() ? left : right; | 11291 if (combined_type->IsClass()) { |
| 11292 if (combined_type->IsClass()) { | 11292 Handle<Map> map = combined_type->AsClass()->Map(); |
| 11293 Handle<Map> map = combined_type->AsClass()->Map(); | 11293 AddCheckMap(left, map); |
| 11294 AddCheckMap(operand_to_check, map); | 11294 AddCheckMap(right, map); |
| 11295 HCompareObjectEqAndBranch* result = | 11295 } else { |
| 11296 New<HCompareObjectEqAndBranch>(left, right); | 11296 BuildCheckHeapObject(left); |
| 11297 return result; | 11297 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_JS_RECEIVER); |
| 11298 BuildCheckHeapObject(right); |
| 11299 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_JS_RECEIVER); |
| 11300 } |
| 11298 } else { | 11301 } else { |
| 11299 BuildCheckHeapObject(operand_to_check); | 11302 // For strict equality we only need to check one side. |
| 11300 Add<HCheckInstanceType>(operand_to_check, | 11303 HValue* operand_to_check = |
| 11301 HCheckInstanceType::IS_JS_RECEIVER); | 11304 left->block()->block_id() < right->block()->block_id() ? left |
| 11302 HCompareObjectEqAndBranch* result = | 11305 : right; |
| 11303 New<HCompareObjectEqAndBranch>(left, right); | 11306 if (combined_type->IsClass()) { |
| 11304 return result; | 11307 Handle<Map> map = combined_type->AsClass()->Map(); |
| 11308 AddCheckMap(operand_to_check, map); |
| 11309 } else { |
| 11310 BuildCheckHeapObject(operand_to_check); |
| 11311 Add<HCheckInstanceType>(operand_to_check, |
| 11312 HCheckInstanceType::IS_JS_RECEIVER); |
| 11313 } |
| 11305 } | 11314 } |
| 11315 HCompareObjectEqAndBranch* result = |
| 11316 New<HCompareObjectEqAndBranch>(left, right); |
| 11317 return result; |
| 11306 } else { | 11318 } else { |
| 11307 if (combined_type->IsClass()) { | 11319 if (combined_type->IsClass()) { |
| 11308 // TODO(bmeurer): This is an optimized version of an x < y, x > y, | 11320 // TODO(bmeurer): This is an optimized version of an x < y, x > y, |
| 11309 // x <= y or x >= y, where both x and y are spec objects with the | 11321 // x <= y or x >= y, where both x and y are spec objects with the |
| 11310 // same map. The CompareIC collects this map for us. So if we know | 11322 // same map. The CompareIC collects this map for us. So if we know |
| 11311 // that there's no @@toPrimitive on the map (including the prototype | 11323 // that there's no @@toPrimitive on the map (including the prototype |
| 11312 // chain), and both valueOf and toString are the default initial | 11324 // chain), and both valueOf and toString are the default initial |
| 11313 // implementations (on the %ObjectPrototype%), then we can reduce | 11325 // implementations (on the %ObjectPrototype%), then we can reduce |
| 11314 // the comparison to map checks on x and y, because the comparison | 11326 // the comparison to map checks on x and y, because the comparison |
| 11315 // will turn into a comparison of "[object CLASS]" to itself (the | 11327 // will turn into a comparison of "[object CLASS]" to itself (the |
| (...skipping 1681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12997 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13009 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12998 } | 13010 } |
| 12999 | 13011 |
| 13000 #ifdef DEBUG | 13012 #ifdef DEBUG |
| 13001 graph_->Verify(false); // No full verify. | 13013 graph_->Verify(false); // No full verify. |
| 13002 #endif | 13014 #endif |
| 13003 } | 13015 } |
| 13004 | 13016 |
| 13005 } // namespace internal | 13017 } // namespace internal |
| 13006 } // namespace v8 | 13018 } // namespace v8 |
| OLD | NEW |