OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1991 | 1991 |
1992 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) | 1992 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer) |
1993 | 1993 |
1994 protected: | 1994 protected: |
1995 virtual bool DataEquals(HValue* other) { return true; } | 1995 virtual bool DataEquals(HValue* other) { return true; } |
1996 }; | 1996 }; |
1997 | 1997 |
1998 | 1998 |
1999 class HCheckMap: public HTemplateInstruction<2> { | 1999 class HCheckMap: public HTemplateInstruction<2> { |
2000 public: | 2000 public: |
2001 HCheckMap(HValue* value, | 2001 HCheckMap(HValue* value, Handle<Map> map, HValue* typecheck = NULL) { |
2002 Handle<Map> map, | |
2003 HValue* typecheck = NULL, | |
2004 CompareMapMode mode = REQUIRE_EXACT_MAP) | |
2005 : map_(map), | |
2006 mode_(mode) { | |
2007 SetOperandAt(0, value); | 2002 SetOperandAt(0, value); |
2008 // If callers don't depend on a typecheck, they can pass in NULL. In that | 2003 // If callers don't depend on a typecheck, they can pass in NULL. In that |
2009 // case we use a copy of the |value| argument as a dummy value. | 2004 // case we use a copy of the |value| argument as a dummy value. |
2010 SetOperandAt(1, typecheck != NULL ? typecheck : value); | 2005 SetOperandAt(1, typecheck != NULL ? typecheck : value); |
2011 set_representation(Representation::Tagged()); | 2006 set_representation(Representation::Tagged()); |
2012 SetFlag(kUseGVN); | 2007 SetFlag(kUseGVN); |
2013 SetGVNFlag(kDependsOnMaps); | 2008 SetGVNFlag(kDependsOnMaps); |
2014 // If the map to check doesn't have the untransitioned elements, it must not | 2009 SetGVNFlag(kDependsOnElementsKind); |
2015 // be hoisted above TransitionElements instructions. | 2010 map_set()->Add(map); |
2016 if (mode == REQUIRE_EXACT_MAP || !map->has_fast_smi_only_elements()) { | 2011 } |
2017 SetGVNFlag(kDependsOnElementsKind); | 2012 HCheckMap(HValue* value, SmallMapList* maps) { |
| 2013 SetOperandAt(0, value); |
| 2014 SetOperandAt(1, value); |
| 2015 set_representation(Representation::Tagged()); |
| 2016 SetFlag(kUseGVN); |
| 2017 SetGVNFlag(kDependsOnMaps); |
| 2018 SetGVNFlag(kDependsOnElementsKind); |
| 2019 for (int i = 0; i < maps->length(); i++) { |
| 2020 map_set()->Add(maps->at(i)); |
2018 } | 2021 } |
2019 has_element_transitions_ = | 2022 map_set()->Sort(); |
2020 map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL || | 2023 } |
2021 map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL; | 2024 |
| 2025 static HCheckMap* NewWithTransitions(HValue* object, Handle<Map> map) { |
| 2026 HCheckMap* check_map = new HCheckMap(object, map); |
| 2027 SmallMapList* map_set = check_map->map_set(); |
| 2028 |
| 2029 // If the map to check has the untransitioned elements, it can be hoisted |
| 2030 // above TransitionElements instructions. |
| 2031 if (map->has_fast_smi_only_elements()) { |
| 2032 check_map->ClearGVNFlag(kDependsOnElementsKind); |
| 2033 } |
| 2034 |
| 2035 Map* transitioned_fast_element_map = |
| 2036 map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL); |
| 2037 ASSERT(transitioned_fast_element_map == NULL || |
| 2038 map->elements_kind() != FAST_ELEMENTS); |
| 2039 if (transitioned_fast_element_map != NULL) { |
| 2040 map_set->Add(Handle<Map>(transitioned_fast_element_map)); |
| 2041 } |
| 2042 Map* transitioned_double_map = |
| 2043 map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL); |
| 2044 ASSERT(transitioned_double_map == NULL || |
| 2045 map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); |
| 2046 if (transitioned_double_map != NULL) { |
| 2047 map_set->Add(Handle<Map>(transitioned_double_map)); |
| 2048 } |
| 2049 map_set->Sort(); |
| 2050 |
| 2051 return check_map; |
2022 } | 2052 } |
2023 | 2053 |
2024 virtual Representation RequiredInputRepresentation(int index) { | 2054 virtual Representation RequiredInputRepresentation(int index) { |
2025 return Representation::Tagged(); | 2055 return Representation::Tagged(); |
2026 } | 2056 } |
2027 virtual void PrintDataTo(StringStream* stream); | 2057 virtual void PrintDataTo(StringStream* stream); |
2028 virtual HType CalculateInferredType(); | 2058 virtual HType CalculateInferredType(); |
2029 | 2059 |
2030 HValue* value() { return OperandAt(0); } | 2060 HValue* value() { return OperandAt(0); } |
2031 Handle<Map> map() const { return map_; } | 2061 SmallMapList* map_set() { return &map_set_; } |
2032 CompareMapMode mode() const { return mode_; } | |
2033 | 2062 |
2034 DECLARE_CONCRETE_INSTRUCTION(CheckMap) | 2063 DECLARE_CONCRETE_INSTRUCTION(CheckMap) |
2035 | 2064 |
2036 protected: | 2065 protected: |
2037 virtual bool DataEquals(HValue* other) { | 2066 virtual bool DataEquals(HValue* other) { |
2038 HCheckMap* b = HCheckMap::cast(other); | 2067 HCheckMap* b = HCheckMap::cast(other); |
2039 // Two CheckMaps instructions are DataEqual if their maps are identical and | 2068 // Relies on the fact that map_set has been sorted before. |
2040 // they have the same mode. The mode comparison can be ignored if the map | 2069 if (map_set()->length() != b->map_set()->length()) return false; |
2041 // has no elements transitions. | 2070 for (int i = 0; i < map_set()->length(); i++) { |
2042 return map_.is_identical_to(b->map()) && | 2071 if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false; |
2043 (b->mode() == mode() || !has_element_transitions_); | 2072 } |
| 2073 return true; |
2044 } | 2074 } |
2045 | 2075 |
2046 private: | 2076 private: |
2047 bool has_element_transitions_; | 2077 SmallMapList map_set_; |
2048 Handle<Map> map_; | |
2049 CompareMapMode mode_; | |
2050 }; | 2078 }; |
2051 | 2079 |
2052 | 2080 |
2053 class HCheckFunction: public HUnaryOperation { | 2081 class HCheckFunction: public HUnaryOperation { |
2054 public: | 2082 public: |
2055 HCheckFunction(HValue* value, Handle<JSFunction> function) | 2083 HCheckFunction(HValue* value, Handle<JSFunction> function) |
2056 : HUnaryOperation(value), target_(function) { | 2084 : HUnaryOperation(value), target_(function) { |
2057 set_representation(Representation::Tagged()); | 2085 set_representation(Representation::Tagged()); |
2058 SetFlag(kUseGVN); | 2086 SetFlag(kUseGVN); |
2059 } | 2087 } |
(...skipping 2717 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4777 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); | 4805 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex); |
4778 }; | 4806 }; |
4779 | 4807 |
4780 | 4808 |
4781 #undef DECLARE_INSTRUCTION | 4809 #undef DECLARE_INSTRUCTION |
4782 #undef DECLARE_CONCRETE_INSTRUCTION | 4810 #undef DECLARE_CONCRETE_INSTRUCTION |
4783 | 4811 |
4784 } } // namespace v8::internal | 4812 } } // namespace v8::internal |
4785 | 4813 |
4786 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 4814 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |