Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 304703002: Split GuardField into GuardFieldType and GuardFieldLength instructions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 case kFloat64x2Cid: 212 case kFloat64x2Cid:
213 return kUnboxedFloat64x2; 213 return kUnboxedFloat64x2;
214 default: 214 default:
215 UNREACHABLE(); 215 UNREACHABLE();
216 } 216 }
217 } 217 }
218 return kTagged; 218 return kTagged;
219 } 219 }
220 220
221 221
222 bool GuardFieldInstr::AttributesEqual(Instruction* other) const { 222 bool GuardFieldClassInstr::AttributesEqual(Instruction* other) const {
223 return field().raw() == other->AsGuardField()->field().raw(); 223 return field().raw() == other->AsGuardFieldClass()->field().raw();
224 } 224 }
225 225
226 226
227 bool GuardFieldLengthInstr::AttributesEqual(Instruction* other) const {
228 return field().raw() == other->AsGuardFieldLength()->field().raw();
229 }
230
231
227 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const { 232 bool AssertAssignableInstr::AttributesEqual(Instruction* other) const {
228 AssertAssignableInstr* other_assert = other->AsAssertAssignable(); 233 AssertAssignableInstr* other_assert = other->AsAssertAssignable();
229 ASSERT(other_assert != NULL); 234 ASSERT(other_assert != NULL);
230 // This predicate has to be commutative for DominatorBasedCSE to work. 235 // This predicate has to be commutative for DominatorBasedCSE to work.
231 // TODO(fschneider): Eliminate more asserts with subtype relation. 236 // TODO(fschneider): Eliminate more asserts with subtype relation.
232 return dst_type().raw() == other_assert->dst_type().raw(); 237 return dst_type().raw() == other_assert->dst_type().raw();
233 } 238 }
234 239
235 240
236 bool StrictCompareInstr::AttributesEqual(Instruction* other) const { 241 bool StrictCompareInstr::AttributesEqual(Instruction* other) const {
(...skipping 1710 matching lines...) Expand 10 before | Expand all | Expand 10 after
1947 Definition* replacement = CanonicalizeStrictCompare(this, &negated); 1952 Definition* replacement = CanonicalizeStrictCompare(this, &negated);
1948 if (negated && replacement->IsComparison()) { 1953 if (negated && replacement->IsComparison()) {
1949 ASSERT(replacement != this); 1954 ASSERT(replacement != this);
1950 replacement->AsComparison()->NegateComparison(); 1955 replacement->AsComparison()->NegateComparison();
1951 } 1956 }
1952 return replacement; 1957 return replacement;
1953 } 1958 }
1954 1959
1955 1960
1956 Instruction* CheckClassInstr::Canonicalize(FlowGraph* flow_graph) { 1961 Instruction* CheckClassInstr::Canonicalize(FlowGraph* flow_graph) {
1957 // TODO(vegorov): Replace class checks with null checks when ToNullableCid
1958 // matches.
1959
1960 const intptr_t value_cid = value()->Type()->ToCid(); 1962 const intptr_t value_cid = value()->Type()->ToCid();
1961 if (value_cid == kDynamicCid) { 1963 if (value_cid == kDynamicCid) {
1962 return this; 1964 return this;
1963 } 1965 }
1964 1966
1965 return unary_checks().HasReceiverClassId(value_cid) ? NULL : this; 1967 return unary_checks().HasReceiverClassId(value_cid) ? NULL : this;
1966 } 1968 }
1967 1969
1968 1970
1969 Instruction* GuardFieldInstr::Canonicalize(FlowGraph* flow_graph) { 1971 Instruction* GuardFieldClassInstr::Canonicalize(FlowGraph* flow_graph) {
1970 if (field().guarded_cid() == kDynamicCid) { 1972 if (field().guarded_cid() == kDynamicCid) {
1971 return NULL; // Nothing to guard. 1973 return NULL; // Nothing to guard.
1972 } 1974 }
1973 1975
1974 if (field().guarded_list_length() != Field::kNoFixedLength) {
1975 // We are still guarding the list length. Check if length is statically
1976 // known.
1977 StaticCallInstr* call = value()->definition()->AsStaticCall();
1978 if (call != NULL) {
1979 ConstantInstr* length = NULL;
1980 if (call->is_known_list_constructor() &&
1981 LoadFieldInstr::IsFixedLengthArrayCid(call->Type()->ToCid())) {
1982 length = call->ArgumentAt(1)->AsConstant();
1983 }
1984 if (call->is_native_list_factory()) {
1985 length = call->ArgumentAt(0)->AsConstant();
1986 }
1987 if ((length != NULL) && length->value().IsSmi()) {
1988 intptr_t known_length = Smi::Cast(length->value()).Value();
1989 return (known_length != field().guarded_list_length()) ? this : NULL;
1990 }
1991 }
1992 return this;
1993 }
1994
1995 if (field().is_nullable() && value()->Type()->IsNull()) { 1976 if (field().is_nullable() && value()->Type()->IsNull()) {
1996 return NULL; 1977 return NULL;
1997 } 1978 }
1998 1979
1999 const intptr_t cid = field().is_nullable() ? value()->Type()->ToNullableCid() 1980 const intptr_t cid = field().is_nullable() ? value()->Type()->ToNullableCid()
2000 : value()->Type()->ToCid(); 1981 : value()->Type()->ToCid();
2001 if (field().guarded_cid() == cid) { 1982 if (field().guarded_cid() == cid) {
2002 return NULL; // Value is guaranteed to have this cid. 1983 return NULL; // Value is guaranteed to have this cid.
2003 } 1984 }
2004 1985
2005 return this; 1986 return this;
2006 } 1987 }
2007 1988
2008 1989
1990 Instruction* GuardFieldLengthInstr::Canonicalize(FlowGraph* flow_graph) {
1991 if (!field().needs_length_check()) {
1992 return NULL; // Nothing to guard.
1993 }
1994
1995 const intptr_t expected_length = field().guarded_list_length();
1996 if (expected_length == Field::kUnknownFixedLength) {
1997 return this;
1998 }
1999
2000 // Check if length is statically known.
2001 StaticCallInstr* call = value()->definition()->AsStaticCall();
2002 if (call == NULL) {
2003 return this;
2004 }
2005
2006 ConstantInstr* length = NULL;
2007 if (call->is_known_list_constructor() &&
2008 LoadFieldInstr::IsFixedLengthArrayCid(call->Type()->ToCid())) {
2009 length = call->ArgumentAt(1)->AsConstant();
2010 }
2011 if (call->is_native_list_factory()) {
2012 length = call->ArgumentAt(0)->AsConstant();
2013 }
2014 if ((length != NULL) &&
2015 length->value().IsSmi() &&
2016 Smi::Cast(length->value()).Value() == expected_length) {
2017 return NULL; // Expected length matched.
2018 }
2019
2020 return this;
2021 }
2022
2023
2009 Instruction* CheckSmiInstr::Canonicalize(FlowGraph* flow_graph) { 2024 Instruction* CheckSmiInstr::Canonicalize(FlowGraph* flow_graph) {
2010 return (value()->Type()->ToCid() == kSmiCid) ? NULL : this; 2025 return (value()->Type()->ToCid() == kSmiCid) ? NULL : this;
2011 } 2026 }
2012 2027
2013 2028
2014 Instruction* CheckEitherNonSmiInstr::Canonicalize(FlowGraph* flow_graph) { 2029 Instruction* CheckEitherNonSmiInstr::Canonicalize(FlowGraph* flow_graph) {
2015 if ((left()->Type()->ToCid() == kDoubleCid) || 2030 if ((left()->Type()->ToCid() == kDoubleCid) ||
2016 (right()->Type()->ToCid() == kDoubleCid)) { 2031 (right()->Type()->ToCid() == kDoubleCid)) {
2017 return NULL; // Remove from the graph. 2032 return NULL; // Remove from the graph.
2018 } 2033 }
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after
3455 case Token::kTRUNCDIV: return 0; 3470 case Token::kTRUNCDIV: return 0;
3456 case Token::kMOD: return 1; 3471 case Token::kMOD: return 1;
3457 default: UNIMPLEMENTED(); return -1; 3472 default: UNIMPLEMENTED(); return -1;
3458 } 3473 }
3459 } 3474 }
3460 3475
3461 3476
3462 #undef __ 3477 #undef __
3463 3478
3464 } // namespace dart 3479 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698