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/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
10 #include "src/ast-numbering.h" | 10 #include "src/ast-numbering.h" |
(...skipping 11560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11571 return result; | 11571 return result; |
11572 } else { | 11572 } else { |
11573 BuildCheckHeapObject(operand_to_check); | 11573 BuildCheckHeapObject(operand_to_check); |
11574 Add<HCheckInstanceType>(operand_to_check, | 11574 Add<HCheckInstanceType>(operand_to_check, |
11575 HCheckInstanceType::IS_SPEC_OBJECT); | 11575 HCheckInstanceType::IS_SPEC_OBJECT); |
11576 HCompareObjectEqAndBranch* result = | 11576 HCompareObjectEqAndBranch* result = |
11577 New<HCompareObjectEqAndBranch>(left, right); | 11577 New<HCompareObjectEqAndBranch>(left, right); |
11578 return result; | 11578 return result; |
11579 } | 11579 } |
11580 } else { | 11580 } else { |
| 11581 if (combined_type->IsClass()) { |
| 11582 // TODO(bmeurer): This is an optimized version of an x < y, x > y, |
| 11583 // x <= y or x >= y, where both x and y are spec objects with the |
| 11584 // same map. The CompareIC collects this map for us. So if we know |
| 11585 // that there's no @@toPrimitive on the map (including the prototype |
| 11586 // chain), and both valueOf and toString are the default initial |
| 11587 // implementations (on the %ObjectPrototype%), then we can reduce |
| 11588 // the comparison to map checks on x and y, because the comparison |
| 11589 // will turn into a comparison of "[object CLASS]" to itself (the |
| 11590 // default outcome of toString, since valueOf returns a spec object). |
| 11591 // This is pretty much adhoc, so in TurboFan we could do a lot better |
| 11592 // and inline the interesting parts of ToPrimitive (actually we could |
| 11593 // even do that in Crankshaft but we don't want to waste too much |
| 11594 // time on this now). |
| 11595 DCHECK(Token::IsOrderedRelationalCompareOp(op)); |
| 11596 Handle<Map> map = combined_type->AsClass()->Map(); |
| 11597 PropertyAccessInfo value_of(this, LOAD, map, |
| 11598 isolate()->factory()->valueOf_string()); |
| 11599 PropertyAccessInfo to_primitive( |
| 11600 this, LOAD, map, isolate()->factory()->to_primitive_symbol()); |
| 11601 PropertyAccessInfo to_string(this, LOAD, map, |
| 11602 isolate()->factory()->toString_string()); |
| 11603 if (to_primitive.CanAccessMonomorphic() && !to_primitive.IsFound() && |
| 11604 value_of.CanAccessMonomorphic() && value_of.IsDataConstant() && |
| 11605 value_of.constant().is_identical_to(isolate()->object_value_of()) && |
| 11606 to_string.CanAccessMonomorphic() && to_string.IsDataConstant() && |
| 11607 to_string.constant().is_identical_to( |
| 11608 isolate()->object_to_string())) { |
| 11609 // We depend on the prototype chain to stay the same, because we |
| 11610 // also need to deoptimize when someone installs @@toPrimitive |
| 11611 // somewhere in the prototype chain. |
| 11612 BuildCheckPrototypeMaps(handle(JSObject::cast(map->prototype())), |
| 11613 Handle<JSObject>::null()); |
| 11614 AddCheckMap(left, map); |
| 11615 AddCheckMap(right, map); |
| 11616 // The caller expects a branch instruction, so make it happy. |
| 11617 return New<HBranch>( |
| 11618 graph()->GetConstantBool(op == Token::LTE || op == Token::GTE)); |
| 11619 } |
| 11620 } |
11581 Bailout(kUnsupportedNonPrimitiveCompare); | 11621 Bailout(kUnsupportedNonPrimitiveCompare); |
11582 return NULL; | 11622 return NULL; |
11583 } | 11623 } |
11584 } else if (combined_type->Is(Type::InternalizedString()) && | 11624 } else if (combined_type->Is(Type::InternalizedString()) && |
11585 Token::IsEqualityOp(op)) { | 11625 Token::IsEqualityOp(op)) { |
11586 // If we have a constant argument, it should be consistent with the type | 11626 // If we have a constant argument, it should be consistent with the type |
11587 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). | 11627 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). |
11588 if ((left->IsConstant() && | 11628 if ((left->IsConstant() && |
11589 !HConstant::cast(left)->HasInternalizedStringValue()) || | 11629 !HConstant::cast(left)->HasInternalizedStringValue()) || |
11590 (right->IsConstant() && | 11630 (right->IsConstant() && |
(...skipping 1972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13563 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13603 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13564 } | 13604 } |
13565 | 13605 |
13566 #ifdef DEBUG | 13606 #ifdef DEBUG |
13567 graph_->Verify(false); // No full verify. | 13607 graph_->Verify(false); // No full verify. |
13568 #endif | 13608 #endif |
13569 } | 13609 } |
13570 | 13610 |
13571 } // namespace internal | 13611 } // namespace internal |
13572 } // namespace v8 | 13612 } // namespace v8 |
OLD | NEW |