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

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

Issue 10025031: Factored out common cases for type tests, used by instance of and assert assigneable. Using inlined… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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/code_generator_ia32.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/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/code_patcher.h" 7 #include "vm/code_patcher.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/dart_api_impl.h" 9 #include "vm/dart_api_impl.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 return String::NewSymbol("int"); 404 return String::NewSymbol("int");
405 } else { 405 } else {
406 return Type::Handle(value.GetType()).Name(); 406 return Type::Handle(value.GetType()).Name();
407 } 407 }
408 } 408 }
409 409
410 410
411 // Check that the type of the given instance is a subtype of the given type and 411 // Check that the type of the given instance is a subtype of the given type and
412 // can therefore be assigned. 412 // can therefore be assigned.
413 // Arg0: index of the token of the assignment (source location). 413 // Arg0: index of the token of the assignment (source location).
414 // Arg1: node-id of the assignemnt.
414 // Arg1: instance being assigned. 415 // Arg1: instance being assigned.
415 // Arg2: type being assigned to. 416 // Arg2: type being assigned to.
416 // Arg3: type arguments of the instantiator of the type being assigned to. 417 // Arg3: type arguments of the instantiator of the type being assigned to.
417 // Arg4: name of variable being assigned to. 418 // Arg4: name of variable being assigned to.
418 // Return value: instance if a subtype, otherwise throw a TypeError. 419 // Return value: instance if a subtype, otherwise throw a TypeError.
419 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) { 420 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) {
420 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count()); 421 ASSERT(arguments.Count() == kTypeCheckRuntimeEntry.argument_count());
421 // TODO(regis): Get the token index from the PcDesc (via DartFrame). 422 // TODO(regis): Get the token index from the PcDesc (via DartFrame).
422 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value(); 423 intptr_t location = Smi::CheckedHandle(arguments.At(0)).Value();
423 const Instance& src_instance = Instance::CheckedHandle(arguments.At(1)); 424 intptr_t node_id = Smi::CheckedHandle(arguments.At(1)).Value();
424 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(2)); 425 const Instance& src_instance = Instance::CheckedHandle(arguments.At(2));
426 const AbstractType& dst_type = AbstractType::CheckedHandle(arguments.At(3));
425 const AbstractTypeArguments& dst_type_instantiator = 427 const AbstractTypeArguments& dst_type_instantiator =
426 AbstractTypeArguments::CheckedHandle(arguments.At(3)); 428 AbstractTypeArguments::CheckedHandle(arguments.At(4));
427 const String& dst_name = String::CheckedHandle(arguments.At(4)); 429 const String& dst_name = String::CheckedHandle(arguments.At(5));
428 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. 430 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
429 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. 431 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
430 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. 432 ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
431 433
432 Error& malformed_error = Error::Handle(); 434 Error& malformed_error = Error::Handle();
433 const bool is_instance_of = src_instance.IsInstanceOf( 435 const bool is_instance_of = src_instance.IsInstanceOf(
434 dst_type, dst_type_instantiator, &malformed_error); 436 dst_type, dst_type_instantiator, &malformed_error);
435 437
436 if (FLAG_trace_type_checks) { 438 if (FLAG_trace_type_checks) {
437 const Type& src_type = Type::Handle(src_instance.GetType()); 439 const Type& src_type = Type::Handle(src_instance.GetType());
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } 476 }
475 String& malformed_error_message = String::Handle(); 477 String& malformed_error_message = String::Handle();
476 if (!malformed_error.IsNull()) { 478 if (!malformed_error.IsNull()) {
477 ASSERT(FLAG_enable_type_checks); 479 ASSERT(FLAG_enable_type_checks);
478 malformed_error_message = String::New(malformed_error.ToErrorCString()); 480 malformed_error_message = String::New(malformed_error.ToErrorCString());
479 } 481 }
480 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name, 482 Exceptions::CreateAndThrowTypeError(location, src_type_name, dst_type_name,
481 dst_name, malformed_error_message); 483 dst_name, malformed_error_message);
482 UNREACHABLE(); 484 UNREACHABLE();
483 } 485 }
486 // Update cache: add class of instance and result.
487 if (dst_type.IsInstantiated() &&
488 !Class::Handle(dst_type.type_class()).HasTypeArguments()) {
489 DartFrameIterator iterator;
490 DartFrame* caller_frame = iterator.NextFrame();
491 ASSERT(caller_frame != NULL);
492 const Code& code = Code::Handle(caller_frame->LookupDartCode());
493 ASSERT(!code.IsNull());
494 uword loc = code.GetTypeTestAtNodeId(node_id);
495 if (loc != 0) {
496 // Found type test cache.
497 Array& value = Array::Handle(CodePatcher::GetTypeTestArray(loc));
498 const Class& src_instance_class = Class::Handle(src_instance.clazz());
499
500 #if defined(DEBUG)
501 // Check for duplicate entries.
502 Class& last_checked = Class::Handle();
503 for (intptr_t i = 0; i < value.Length(); i += 2) {
504 last_checked ^= value.At(i);
505 ASSERT(last_checked.raw() != src_instance_class.raw());
506 }
507 // Array must be null terminated.
508 ASSERT(last_checked.IsNull());
509 #endif
510
511 ASSERT(!value.IsNull());
512 intptr_t old_len = value.Length();
513 value = value.Grow(value, old_len + 2);
514 value.SetAt(old_len - 2, src_instance_class);
515 value.SetAt(old_len - 1, Bool::ZoneHandle(Bool::True()));
516 CodePatcher::SetTypeTestArray(loc, value);
517 }
518 }
484 arguments.SetReturn(src_instance); 519 arguments.SetReturn(src_instance);
485 } 520 }
486 521
487 522
488 // Report that the type of the given object is not bool in conditional context. 523 // Report that the type of the given object is not bool in conditional context.
489 // Arg0: index of the token of the assignment (source location). 524 // Arg0: index of the token of the assignment (source location).
490 // Arg1: bad object. 525 // Arg1: bad object.
491 // Return value: none, throws a TypeError. 526 // Return value: none, throws a TypeError.
492 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) { 527 DEFINE_RUNTIME_ENTRY(ConditionTypeError, 2) {
493 ASSERT(arguments.Count() == 528 ASSERT(arguments.Count() ==
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 } 1464 }
1430 } 1465 }
1431 } 1466 }
1432 // The cache is null terminated, therefore the loop above should never 1467 // The cache is null terminated, therefore the loop above should never
1433 // terminate by itself. 1468 // terminate by itself.
1434 UNREACHABLE(); 1469 UNREACHABLE();
1435 return Code::null(); 1470 return Code::null();
1436 } 1471 }
1437 1472
1438 } // namespace dart 1473 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_generator_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698