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

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

Issue 10578018: Fix type test elimination using static type propagation in new compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 if (dst_type.IsVoidType()) { 332 if (dst_type.IsVoidType()) {
333 return true; 333 return true;
334 } 334 }
335 335
336 // If nothing is known about the value, as is the case for passed-in 336 // If nothing is known about the value, as is the case for passed-in
337 // parameters, the test cannot be eliminated. 337 // parameters, the test cannot be eliminated.
338 if (value == NULL) { 338 if (value == NULL) {
339 return false; 339 return false;
340 } 340 }
341 341
342 // If nothing is known about the static type of the value, the test cannot be 342 // Consider the static type of the value.
343 // eliminated.
344 const AbstractType& static_type = AbstractType::Handle(value->StaticType()); 343 const AbstractType& static_type = AbstractType::Handle(value->StaticType());
345 ASSERT(!static_type.IsMalformed()); 344 ASSERT(!static_type.IsMalformed());
346 if (static_type.IsDynamicType()) {
347 return false;
348 }
349 345
350 // If the static type of the value is void, the only allowed value is null, 346 // If the static type of the value is void, the only allowed value is null,
351 // which must be verified by the type test. 347 // which must be verified by the type test.
352 if (static_type.IsVoidType()) { 348 if (static_type.IsVoidType()) {
353 // TODO(regis): Eliminate the test if the value is constant null. 349 // TODO(regis): Eliminate the test if the value is constant null.
354 return false; 350 return false;
355 } 351 }
356 352
357 // Eliminate the test if it can be performed successfully at compile time. 353 // If the static type of the value is NullType, the type test is eliminated.
358 if (static_type.IsNullType()) { 354 if (static_type.IsNullType()) {
359 // There are only three instances that can be of Class Null: 355 // There are only three instances that can be of Class Null:
360 // Object::null(), Object::sentinel(), and Object::transition_sentinel(). 356 // Object::null(), Object::sentinel(), and Object::transition_sentinel().
361 // The inline code and run time code performing the type check will never 357 // The inline code and run time code performing the type check will never
362 // encounter the 2 sentinel values. The type check of a sentinel value 358 // encounter the 2 sentinel values. The type check of a sentinel value
363 // will always be eliminated here, because these sentinel values can only 359 // will always be eliminated here, because these sentinel values can only
364 // be encountered as constants, never as actual value of a heap object 360 // be encountered as constants, never as actual value of a heap object
365 // being type checked. 361 // being type checked.
366 return true; 362 return true;
367 } 363 }
368 if (static_type.IsType() && 364
369 Class::Handle(static_type.type_class()).HasTypeArguments()) { 365 // The run time type of the value is guaranteed to be a subtype of the compile
370 // TODO(regis): Special tests need to be added. 366 // time static type of the value. However, establishing here that the static
371 return false; 367 // type is a subtype of the destination type does not guarantee that the run
372 } 368 // time type will also be a subtype of the destination type, because the
369 // subtype relation is not transitive.
370 // However, the 'more specific than' relation is transitive and is used here.
371 // In other words, if the static type of the value is more specific than the
372 // destination type, the run time type of the value, which is guaranteed to
373 // be a subtype of the static type, is also guaranteed to be a subtype of the
374 // destination type and the type check can therefore be eliminated.
373 Error& malformed_error = Error::Handle(); 375 Error& malformed_error = Error::Handle();
374 if (!dst_type.IsMalformed() && 376 if (static_type.IsMoreSpecificThan(dst_type, &malformed_error)) {
375 static_type.IsSubtypeOf(dst_type, &malformed_error)) {
376 return true; 377 return true;
377 } 378 }
378 379
379 return false; 380 return false;
380 } 381 }
381 382
382 383
383 // <Expression> :: Assignable { expr: <Expression> 384 // <Expression> :: Assignable { expr: <Expression>
384 // type: AbstractType 385 // type: AbstractType
385 // dst_name: String } 386 // dst_name: String }
(...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after
2728 char* chars = reinterpret_cast<char*>( 2729 char* chars = reinterpret_cast<char*>(
2729 Isolate::Current()->current_zone()->Allocate(len)); 2730 Isolate::Current()->current_zone()->Allocate(len));
2730 OS::SNPrint(chars, len, kFormat, function_name, reason); 2731 OS::SNPrint(chars, len, kFormat, function_name, reason);
2731 const Error& error = Error::Handle( 2732 const Error& error = Error::Handle(
2732 LanguageError::New(String::Handle(String::New(chars)))); 2733 LanguageError::New(String::Handle(String::New(chars))));
2733 Isolate::Current()->long_jump_base()->Jump(1, error); 2734 Isolate::Current()->long_jump_base()->Jump(1, error);
2734 } 2735 }
2735 2736
2736 2737
2737 } // namespace dart 2738 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698