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

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

Issue 2799373002: Pass a second type argument vector to all type instantiation calls in the VM. (Closed)
Patch Set: addressed comments Created 3 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
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/constant_propagator.cc » ('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) 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/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/ast.h" 8 #include "vm/ast.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 ASSERT(type_arguments.IsNull() || 227 ASSERT(type_arguments.IsNull() ||
228 (type_arguments.IsInstantiated() && 228 (type_arguments.IsInstantiated() &&
229 (type_arguments.Length() >= cls.NumTypeArguments()))); 229 (type_arguments.Length() >= cls.NumTypeArguments())));
230 instance.SetTypeArguments(type_arguments); 230 instance.SetTypeArguments(type_arguments);
231 } 231 }
232 232
233 233
234 // Instantiate type. 234 // Instantiate type.
235 // Arg0: uninstantiated type. 235 // Arg0: uninstantiated type.
236 // Arg1: instantiator type arguments. 236 // Arg1: instantiator type arguments.
237 // Arg2: function type arguments.
237 // Return value: instantiated type. 238 // Return value: instantiated type.
238 DEFINE_RUNTIME_ENTRY(InstantiateType, 2) { 239 DEFINE_RUNTIME_ENTRY(InstantiateType, 3) {
239 AbstractType& type = AbstractType::CheckedHandle(zone, arguments.ArgAt(0)); 240 AbstractType& type = AbstractType::CheckedHandle(zone, arguments.ArgAt(0));
240 const TypeArguments& instantiator = 241 const TypeArguments& instantiator_type_arguments =
241 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1)); 242 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
243 const TypeArguments& function_type_arguments =
244 TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
242 ASSERT(!type.IsNull() && !type.IsInstantiated()); 245 ASSERT(!type.IsNull() && !type.IsInstantiated());
243 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); 246 ASSERT(instantiator_type_arguments.IsNull() ||
247 instantiator_type_arguments.IsInstantiated());
248 ASSERT(function_type_arguments.IsNull() ||
249 function_type_arguments.IsInstantiated());
244 Error& bound_error = Error::Handle(zone); 250 Error& bound_error = Error::Handle(zone);
245 type = 251 type =
246 type.InstantiateFrom(instantiator, &bound_error, NULL, NULL, Heap::kOld); 252 type.InstantiateFrom(instantiator_type_arguments, function_type_arguments,
253 &bound_error, NULL, NULL, Heap::kOld);
247 if (!bound_error.IsNull()) { 254 if (!bound_error.IsNull()) {
248 // Throw a dynamic type error. 255 // Throw a dynamic type error.
249 const TokenPosition location = GetCallerLocation(); 256 const TokenPosition location = GetCallerLocation();
250 String& bound_error_message = 257 String& bound_error_message =
251 String::Handle(zone, String::New(bound_error.ToErrorCString())); 258 String::Handle(zone, String::New(bound_error.ToErrorCString()));
252 Exceptions::CreateAndThrowTypeError(location, AbstractType::Handle(zone), 259 Exceptions::CreateAndThrowTypeError(location, AbstractType::Handle(zone),
253 AbstractType::Handle(zone), 260 AbstractType::Handle(zone),
254 Symbols::Empty(), bound_error_message); 261 Symbols::Empty(), bound_error_message);
255 UNREACHABLE(); 262 UNREACHABLE();
256 } 263 }
257 if (type.IsTypeRef()) { 264 if (type.IsTypeRef()) {
258 type = TypeRef::Cast(type).type(); 265 type = TypeRef::Cast(type).type();
259 ASSERT(!type.IsTypeRef()); 266 ASSERT(!type.IsTypeRef());
260 ASSERT(type.IsCanonical()); 267 ASSERT(type.IsCanonical());
261 } 268 }
262 ASSERT(!type.IsNull() && type.IsInstantiated()); 269 ASSERT(!type.IsNull() && type.IsInstantiated());
263 arguments.SetReturn(type); 270 arguments.SetReturn(type);
264 } 271 }
265 272
266 273
267 // Instantiate type arguments. 274 // Instantiate type arguments.
268 // Arg0: uninstantiated type arguments. 275 // Arg0: uninstantiated type arguments.
269 // Arg1: instantiator type arguments. 276 // Arg1: instantiator type arguments.
277 // Arg2: function type arguments.
270 // Return value: instantiated type arguments. 278 // Return value: instantiated type arguments.
271 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 2) { 279 DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 3) {
272 TypeArguments& type_arguments = 280 TypeArguments& type_arguments =
273 TypeArguments::CheckedHandle(zone, arguments.ArgAt(0)); 281 TypeArguments::CheckedHandle(zone, arguments.ArgAt(0));
274 const TypeArguments& instantiator = 282 const TypeArguments& instantiator_type_arguments =
275 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1)); 283 TypeArguments::CheckedHandle(zone, arguments.ArgAt(1));
284 const TypeArguments& function_type_arguments =
285 TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
276 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated()); 286 ASSERT(!type_arguments.IsNull() && !type_arguments.IsInstantiated());
277 ASSERT(instantiator.IsNull() || instantiator.IsInstantiated()); 287 ASSERT(instantiator_type_arguments.IsNull() ||
288 instantiator_type_arguments.IsInstantiated());
289 ASSERT(function_type_arguments.IsNull() ||
290 function_type_arguments.IsInstantiated());
278 // Code inlined in the caller should have optimized the case where the 291 // Code inlined in the caller should have optimized the case where the
279 // instantiator can be reused as type argument vector. 292 // instantiator can be reused as type argument vector.
280 ASSERT(!type_arguments.IsUninstantiatedIdentity()); 293 ASSERT(!type_arguments.IsUninstantiatedIdentity());
281 if (isolate->type_checks()) { 294 if (isolate->type_checks()) {
282 Error& bound_error = Error::Handle(zone); 295 Error& bound_error = Error::Handle(zone);
283 type_arguments = type_arguments.InstantiateAndCanonicalizeFrom( 296 type_arguments = type_arguments.InstantiateAndCanonicalizeFrom(
284 instantiator, &bound_error); 297 instantiator_type_arguments, function_type_arguments, &bound_error);
285 if (!bound_error.IsNull()) { 298 if (!bound_error.IsNull()) {
286 // Throw a dynamic type error. 299 // Throw a dynamic type error.
287 const TokenPosition location = GetCallerLocation(); 300 const TokenPosition location = GetCallerLocation();
288 String& bound_error_message = 301 String& bound_error_message =
289 String::Handle(zone, String::New(bound_error.ToErrorCString())); 302 String::Handle(zone, String::New(bound_error.ToErrorCString()));
290 Exceptions::CreateAndThrowTypeError( 303 Exceptions::CreateAndThrowTypeError(
291 location, AbstractType::Handle(zone), AbstractType::Handle(zone), 304 location, AbstractType::Handle(zone), AbstractType::Handle(zone),
292 Symbols::Empty(), bound_error_message); 305 Symbols::Empty(), bound_error_message);
293 UNREACHABLE(); 306 UNREACHABLE();
294 } 307 }
295 } else { 308 } else {
296 type_arguments = 309 type_arguments = type_arguments.InstantiateAndCanonicalizeFrom(
297 type_arguments.InstantiateAndCanonicalizeFrom(instantiator, NULL); 310 instantiator_type_arguments, function_type_arguments, NULL);
298 } 311 }
299 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated()); 312 ASSERT(type_arguments.IsNull() || type_arguments.IsInstantiated());
300 arguments.SetReturn(type_arguments); 313 arguments.SetReturn(type_arguments);
301 } 314 }
302 315
303 316
304 // Allocate a new context large enough to hold the given number of variables. 317 // Allocate a new context large enough to hold the given number of variables.
305 // Arg0: number of variables. 318 // Arg0: number of variables.
306 // Return value: newly allocated context. 319 // Return value: newly allocated context.
307 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) { 320 DEFINE_RUNTIME_ENTRY(AllocateContext, 1) {
(...skipping 18 matching lines...) Expand all
326 } 339 }
327 arguments.SetReturn(cloned_ctx); 340 arguments.SetReturn(cloned_ctx);
328 } 341 }
329 342
330 343
331 // Helper routine for tracing a type check. 344 // Helper routine for tracing a type check.
332 static void PrintTypeCheck(const char* message, 345 static void PrintTypeCheck(const char* message,
333 const Instance& instance, 346 const Instance& instance,
334 const AbstractType& type, 347 const AbstractType& type,
335 const TypeArguments& instantiator_type_arguments, 348 const TypeArguments& instantiator_type_arguments,
349 const TypeArguments& function_type_arguments,
336 const Bool& result) { 350 const Bool& result) {
337 DartFrameIterator iterator; 351 DartFrameIterator iterator;
338 StackFrame* caller_frame = iterator.NextFrame(); 352 StackFrame* caller_frame = iterator.NextFrame();
339 ASSERT(caller_frame != NULL); 353 ASSERT(caller_frame != NULL);
340 354
341 const AbstractType& instance_type = 355 const AbstractType& instance_type =
342 AbstractType::Handle(instance.GetType(Heap::kNew)); 356 AbstractType::Handle(instance.GetType(Heap::kNew));
343 ASSERT(instance_type.IsInstantiated()); 357 ASSERT(instance_type.IsInstantiated());
344 if (type.IsInstantiated()) { 358 if (type.IsInstantiated()) {
345 OS::PrintErr("%s: '%s' %" Pd " %s '%s' %" Pd " (pc: %#" Px ").\n", message, 359 OS::PrintErr("%s: '%s' %" Pd " %s '%s' %" Pd " (pc: %#" Px ").\n", message,
346 String::Handle(instance_type.Name()).ToCString(), 360 String::Handle(instance_type.Name()).ToCString(),
347 Class::Handle(instance_type.type_class()).id(), 361 Class::Handle(instance_type.type_class()).id(),
348 (result.raw() == Bool::True().raw()) ? "is" : "is !", 362 (result.raw() == Bool::True().raw()) ? "is" : "is !",
349 String::Handle(type.Name()).ToCString(), 363 String::Handle(type.Name()).ToCString(),
350 Class::Handle(type.type_class()).id(), caller_frame->pc()); 364 Class::Handle(type.type_class()).id(), caller_frame->pc());
351 } else { 365 } else {
352 // Instantiate type before printing. 366 // Instantiate type before printing.
353 Error& bound_error = Error::Handle(); 367 Error& bound_error = Error::Handle();
354 const AbstractType& instantiated_type = 368 const AbstractType& instantiated_type =
355 AbstractType::Handle(type.InstantiateFrom( 369 AbstractType::Handle(type.InstantiateFrom(
356 instantiator_type_arguments, &bound_error, NULL, NULL, Heap::kOld)); 370 instantiator_type_arguments, function_type_arguments, &bound_error,
371 NULL, NULL, Heap::kOld));
357 OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#" Px ").\n", 372 OS::PrintErr("%s: '%s' %s '%s' instantiated from '%s' (pc: %#" Px ").\n",
358 message, String::Handle(instance_type.Name()).ToCString(), 373 message, String::Handle(instance_type.Name()).ToCString(),
359 (result.raw() == Bool::True().raw()) ? "is" : "is !", 374 (result.raw() == Bool::True().raw()) ? "is" : "is !",
360 String::Handle(instantiated_type.Name()).ToCString(), 375 String::Handle(instantiated_type.Name()).ToCString(),
361 String::Handle(type.Name()).ToCString(), caller_frame->pc()); 376 String::Handle(type.Name()).ToCString(), caller_frame->pc());
362 if (!bound_error.IsNull()) { 377 if (!bound_error.IsNull()) {
363 OS::Print(" bound error: %s\n", bound_error.ToErrorCString()); 378 OS::Print(" bound error: %s\n", bound_error.ToErrorCString());
364 } 379 }
365 } 380 }
366 const Function& function = 381 const Function& function =
367 Function::Handle(caller_frame->LookupDartFunction()); 382 Function::Handle(caller_frame->LookupDartFunction());
368 OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString()); 383 OS::PrintErr(" -> Function %s\n", function.ToFullyQualifiedCString());
369 } 384 }
370 385
371 386
372 // This updates the type test cache, an array containing 4-value elements 387 // This updates the type test cache, an array containing 5-value elements
373 // (instance class (or function if the instance is a closure), instance type 388 // (instance class (or function if the instance is a closure), instance type
374 // arguments, instantiator type arguments and test_result). It can be applied to 389 // arguments, instantiator type arguments, function type arguments,
375 // classes with type arguments in which case it contains just the result of the 390 // and test_result). It can be applied to classes with type arguments in which
376 // class subtype test, not including the evaluation of type arguments. 391 // case it contains just the result of the class subtype test, not including the
392 // evaluation of type arguments.
377 // This operation is currently very slow (lookup of code is not efficient yet). 393 // This operation is currently very slow (lookup of code is not efficient yet).
378 static void UpdateTypeTestCache( 394 static void UpdateTypeTestCache(
379 const Instance& instance, 395 const Instance& instance,
380 const AbstractType& type, 396 const AbstractType& type,
381 const TypeArguments& instantiator_type_arguments, 397 const TypeArguments& instantiator_type_arguments,
398 const TypeArguments& function_type_arguments,
382 const Bool& result, 399 const Bool& result,
383 const SubtypeTestCache& new_cache) { 400 const SubtypeTestCache& new_cache) {
384 // Since the test is expensive, don't do it unless necessary. 401 // Since the test is expensive, don't do it unless necessary.
385 // The list of disallowed cases will decrease as they are implemented in 402 // The list of disallowed cases will decrease as they are implemented in
386 // inlined assembly. 403 // inlined assembly.
387 if (new_cache.IsNull()) { 404 if (new_cache.IsNull()) {
388 if (FLAG_trace_type_checks) { 405 if (FLAG_trace_type_checks) {
389 OS::Print("UpdateTypeTestCache: cache is null\n"); 406 OS::Print("UpdateTypeTestCache: cache is null\n");
390 } 407 }
391 return; 408 return;
392 } 409 }
393 if (instance.IsSmi()) { 410 if (instance.IsSmi()) {
394 if (FLAG_trace_type_checks) { 411 if (FLAG_trace_type_checks) {
395 OS::Print("UpdateTypeTestCache: instance is Smi\n"); 412 OS::Print("UpdateTypeTestCache: instance is Smi\n");
396 } 413 }
397 return; 414 return;
398 } 415 }
416 // If the type is uninstantiated and refers to parent function type
417 // parameters, the context is required in the type test and the cache
418 // therefore cannot be used.
419 if (!type.IsInstantiated(kParentFunctions)) {
420 if (FLAG_trace_type_checks) {
421 OS::Print(
422 "UpdateTypeTestCache: type refers to parent function's type "
423 "parameters\n");
424 }
425 return;
426 }
399 const Class& instance_class = Class::Handle(instance.clazz()); 427 const Class& instance_class = Class::Handle(instance.clazz());
400 Object& instance_class_id_or_function = Object::Handle(); 428 Object& instance_class_id_or_function = Object::Handle();
401 TypeArguments& instance_type_arguments = TypeArguments::Handle(); 429 TypeArguments& instance_type_arguments = TypeArguments::Handle();
402 if (instance_class.IsClosureClass()) { 430 if (instance_class.IsClosureClass()) {
403 instance_class_id_or_function = Closure::Cast(instance).function(); 431 instance_class_id_or_function = Closure::Cast(instance).function();
404 instance_type_arguments = Closure::Cast(instance).instantiator(); 432 instance_type_arguments = Closure::Cast(instance).instantiator();
405 } else { 433 } else {
406 instance_class_id_or_function = Smi::New(instance_class.id()); 434 instance_class_id_or_function = Smi::New(instance_class.id());
407 if (instance_class.NumTypeArguments() > 0) { 435 if (instance_class.NumTypeArguments() > 0) {
408 instance_type_arguments = instance.GetTypeArguments(); 436 instance_type_arguments = instance.GetTypeArguments();
409 } 437 }
410 } 438 }
411 const intptr_t len = new_cache.NumberOfChecks(); 439 const intptr_t len = new_cache.NumberOfChecks();
412 if (len >= FLAG_max_subtype_cache_entries) { 440 if (len >= FLAG_max_subtype_cache_entries) {
413 return; 441 return;
414 } 442 }
415 #if defined(DEBUG) 443 #if defined(DEBUG)
416 ASSERT(instance_type_arguments.IsNull() || 444 ASSERT(instance_type_arguments.IsNull() ||
417 instance_type_arguments.IsCanonical()); 445 instance_type_arguments.IsCanonical());
418 ASSERT(instantiator_type_arguments.IsNull() || 446 ASSERT(instantiator_type_arguments.IsNull() ||
419 instantiator_type_arguments.IsCanonical()); 447 instantiator_type_arguments.IsCanonical());
448 ASSERT(function_type_arguments.IsNull() ||
449 function_type_arguments.IsCanonical());
420 Object& last_instance_class_id_or_function = Object::Handle(); 450 Object& last_instance_class_id_or_function = Object::Handle();
421 TypeArguments& last_instance_type_arguments = TypeArguments::Handle(); 451 TypeArguments& last_instance_type_arguments = TypeArguments::Handle();
422 TypeArguments& last_instantiator_type_arguments = TypeArguments::Handle(); 452 TypeArguments& last_instantiator_type_arguments = TypeArguments::Handle();
453 TypeArguments& last_function_type_arguments = TypeArguments::Handle();
423 Bool& last_result = Bool::Handle(); 454 Bool& last_result = Bool::Handle();
424 for (intptr_t i = 0; i < len; ++i) { 455 for (intptr_t i = 0; i < len; ++i) {
425 new_cache.GetCheck(i, &last_instance_class_id_or_function, 456 new_cache.GetCheck(i, &last_instance_class_id_or_function,
426 &last_instance_type_arguments, 457 &last_instance_type_arguments,
427 &last_instantiator_type_arguments, &last_result); 458 &last_instantiator_type_arguments,
459 &last_function_type_arguments, &last_result);
428 if ((last_instance_class_id_or_function.raw() == 460 if ((last_instance_class_id_or_function.raw() ==
429 instance_class_id_or_function.raw()) && 461 instance_class_id_or_function.raw()) &&
430 (last_instance_type_arguments.raw() == instance_type_arguments.raw()) && 462 (last_instance_type_arguments.raw() == instance_type_arguments.raw()) &&
431 (last_instantiator_type_arguments.raw() == 463 (last_instantiator_type_arguments.raw() ==
432 instantiator_type_arguments.raw())) { 464 instantiator_type_arguments.raw()) &&
465 (last_function_type_arguments.raw() ==
466 last_function_type_arguments.raw())) {
433 OS::PrintErr(" Error in test cache %p ix: %" Pd ",", new_cache.raw(), i); 467 OS::PrintErr(" Error in test cache %p ix: %" Pd ",", new_cache.raw(), i);
434 PrintTypeCheck(" duplicate cache entry", instance, type, 468 PrintTypeCheck(" duplicate cache entry", instance, type,
435 instantiator_type_arguments, result); 469 instantiator_type_arguments, function_type_arguments,
470 result);
436 UNREACHABLE(); 471 UNREACHABLE();
437 return; 472 return;
438 } 473 }
439 } 474 }
440 #endif 475 #endif
441 new_cache.AddCheck(instance_class_id_or_function, instance_type_arguments, 476 new_cache.AddCheck(instance_class_id_or_function, instance_type_arguments,
442 instantiator_type_arguments, result); 477 instantiator_type_arguments, function_type_arguments,
478 result);
443 if (FLAG_trace_type_checks) { 479 if (FLAG_trace_type_checks) {
444 AbstractType& test_type = AbstractType::Handle(type.raw()); 480 AbstractType& test_type = AbstractType::Handle(type.raw());
445 if (!test_type.IsInstantiated()) { 481 if (!test_type.IsInstantiated()) {
446 Error& bound_error = Error::Handle(); 482 Error& bound_error = Error::Handle();
447 test_type = type.InstantiateFrom(instantiator_type_arguments, 483 test_type = type.InstantiateFrom(instantiator_type_arguments,
448 &bound_error, NULL, NULL, Heap::kNew); 484 function_type_arguments, &bound_error,
485 NULL, NULL, Heap::kNew);
449 ASSERT(bound_error.IsNull()); // Malbounded types are not optimized. 486 ASSERT(bound_error.IsNull()); // Malbounded types are not optimized.
450 } 487 }
451 OS::PrintErr( 488 OS::PrintErr(
452 " Updated test cache %p ix: %" Pd 489 " Updated test cache %p ix: %" Pd
453 " with " 490 " with "
454 "(cid-or-fun: %p, type-args: %p, instantiator: %p, result: %s)\n" 491 "(cid-or-fun: %p, type-args: %p, i-type-args: %p, f-type-args: %p, "
492 "result: %s)\n"
455 " instance [class: (%p '%s' cid: %" Pd 493 " instance [class: (%p '%s' cid: %" Pd
456 "), type-args: %p %s]\n" 494 "), type-args: %p %s]\n"
457 " test-type [class: (%p '%s' cid: %" Pd "), in-type-args: %p %s]\n", 495 " test-type [class: (%p '%s' cid: %" Pd
496 "), i-type-args: %p %s, "
497 ", f-type-args: %p %s]\n",
458 new_cache.raw(), len, 498 new_cache.raw(), len,
459 499
460 instance_class_id_or_function.raw(), instance_type_arguments.raw(), 500 instance_class_id_or_function.raw(), instance_type_arguments.raw(),
461 instantiator_type_arguments.raw(), result.ToCString(), 501 instantiator_type_arguments.raw(), instantiator_type_arguments.raw(),
502 result.ToCString(),
462 503
463 instance_class.raw(), String::Handle(instance_class.Name()).ToCString(), 504 instance_class.raw(), String::Handle(instance_class.Name()).ToCString(),
464 instance_class.id(), instance_type_arguments.raw(), 505 instance_class.id(), instance_type_arguments.raw(),
465 instance_type_arguments.ToCString(), 506 instance_type_arguments.ToCString(),
466 507
467 test_type.type_class(), 508 test_type.type_class(),
468 String::Handle(Class::Handle(test_type.type_class()).Name()) 509 String::Handle(Class::Handle(test_type.type_class()).Name())
469 .ToCString(), 510 .ToCString(),
470 Class::Handle(test_type.type_class()).id(), 511 Class::Handle(test_type.type_class()).id(),
471 instantiator_type_arguments.raw(), 512 instantiator_type_arguments.raw(),
513 instantiator_type_arguments.ToCString(),
514 instantiator_type_arguments.raw(),
472 instantiator_type_arguments.ToCString()); 515 instantiator_type_arguments.ToCString());
473 } 516 }
474 } 517 }
475 518
476 519
477 // Check that the given instance is an instance of the given type. 520 // Check that the given instance is an instance of the given type.
478 // Tested instance may not be null, because the null test is inlined. 521 // Tested instance may not be null, because the null test is inlined.
479 // Arg0: instance being checked. 522 // Arg0: instance being checked.
480 // Arg1: type. 523 // Arg1: type.
481 // Arg2: type arguments of the instantiator of the type. 524 // Arg2: type arguments of the instantiator of the type.
482 // Arg3: SubtypeTestCache. 525 // Arg3: type arguments of the function of the type.
526 // Arg4: SubtypeTestCache.
483 // Return value: true or false, or may throw a type error in checked mode. 527 // Return value: true or false, or may throw a type error in checked mode.
484 DEFINE_RUNTIME_ENTRY(Instanceof, 4) { 528 DEFINE_RUNTIME_ENTRY(Instanceof, 5) {
485 const Instance& instance = Instance::CheckedHandle(zone, arguments.ArgAt(0)); 529 const Instance& instance = Instance::CheckedHandle(zone, arguments.ArgAt(0));
486 const AbstractType& type = 530 const AbstractType& type =
487 AbstractType::CheckedHandle(zone, arguments.ArgAt(1)); 531 AbstractType::CheckedHandle(zone, arguments.ArgAt(1));
488 const TypeArguments& instantiator_type_arguments = 532 const TypeArguments& instantiator_type_arguments =
489 TypeArguments::CheckedHandle(zone, arguments.ArgAt(2)); 533 TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
534 const TypeArguments& function_type_arguments =
535 TypeArguments::CheckedHandle(zone, arguments.ArgAt(3));
490 const SubtypeTestCache& cache = 536 const SubtypeTestCache& cache =
491 SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(3)); 537 SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(4));
492 ASSERT(type.IsFinalized()); 538 ASSERT(type.IsFinalized());
493 ASSERT(!type.IsMalformed()); // Already checked in code generator. 539 ASSERT(!type.IsMalformed()); // Already checked in code generator.
494 ASSERT(!type.IsMalbounded()); // Already checked in code generator. 540 ASSERT(!type.IsMalbounded()); // Already checked in code generator.
495 ASSERT(!type.IsDynamicType()); // No need to check assignment. 541 ASSERT(!type.IsDynamicType()); // No need to check assignment.
496 Error& bound_error = Error::Handle(zone); 542 Error& bound_error = Error::Handle(zone);
497 const Bool& result = Bool::Get( 543 const Bool& result =
498 instance.IsInstanceOf(type, instantiator_type_arguments, &bound_error)); 544 Bool::Get(instance.IsInstanceOf(type, instantiator_type_arguments,
545 function_type_arguments, &bound_error));
499 if (FLAG_trace_type_checks) { 546 if (FLAG_trace_type_checks) {
500 PrintTypeCheck("InstanceOf", instance, type, instantiator_type_arguments, 547 PrintTypeCheck("InstanceOf", instance, type, instantiator_type_arguments,
501 result); 548 function_type_arguments, result);
502 } 549 }
503 if (!result.value() && !bound_error.IsNull()) { 550 if (!result.value() && !bound_error.IsNull()) {
504 // Throw a dynamic type error only if the instanceof test fails. 551 // Throw a dynamic type error only if the instanceof test fails.
505 const TokenPosition location = GetCallerLocation(); 552 const TokenPosition location = GetCallerLocation();
506 String& bound_error_message = 553 String& bound_error_message =
507 String::Handle(zone, String::New(bound_error.ToErrorCString())); 554 String::Handle(zone, String::New(bound_error.ToErrorCString()));
508 Exceptions::CreateAndThrowTypeError(location, AbstractType::Handle(zone), 555 Exceptions::CreateAndThrowTypeError(location, AbstractType::Handle(zone),
509 AbstractType::Handle(zone), 556 AbstractType::Handle(zone),
510 Symbols::Empty(), bound_error_message); 557 Symbols::Empty(), bound_error_message);
511 UNREACHABLE(); 558 UNREACHABLE();
512 } 559 }
513 UpdateTypeTestCache(instance, type, instantiator_type_arguments, result, 560 UpdateTypeTestCache(instance, type, instantiator_type_arguments,
514 cache); 561 function_type_arguments, result, cache);
515 arguments.SetReturn(result); 562 arguments.SetReturn(result);
516 } 563 }
517 564
518 565
519 // Check that the type of the given instance is a subtype of the given type and 566 // Check that the type of the given instance is a subtype of the given type and
520 // can therefore be assigned. 567 // can therefore be assigned.
521 // Arg0: instance being assigned. 568 // Arg0: instance being assigned.
522 // Arg1: type being assigned to. 569 // Arg1: type being assigned to.
523 // Arg2: type arguments of the instantiator of the type being assigned to. 570 // Arg2: type arguments of the instantiator of the type being assigned to.
524 // Arg3: name of variable being assigned to. 571 // Arg3: type arguments of the function of the type being assigned to.
525 // Arg4: SubtypeTestCache. 572 // Arg4: name of variable being assigned to.
573 // Arg5: SubtypeTestCache.
526 // Return value: instance if a subtype, otherwise throw a TypeError. 574 // Return value: instance if a subtype, otherwise throw a TypeError.
527 DEFINE_RUNTIME_ENTRY(TypeCheck, 5) { 575 DEFINE_RUNTIME_ENTRY(TypeCheck, 6) {
528 const Instance& src_instance = 576 const Instance& src_instance =
529 Instance::CheckedHandle(zone, arguments.ArgAt(0)); 577 Instance::CheckedHandle(zone, arguments.ArgAt(0));
530 AbstractType& dst_type = 578 AbstractType& dst_type =
531 AbstractType::CheckedHandle(zone, arguments.ArgAt(1)); 579 AbstractType::CheckedHandle(zone, arguments.ArgAt(1));
532 const TypeArguments& instantiator_type_arguments = 580 const TypeArguments& instantiator_type_arguments =
533 TypeArguments::CheckedHandle(zone, arguments.ArgAt(2)); 581 TypeArguments::CheckedHandle(zone, arguments.ArgAt(2));
534 const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(3)); 582 const TypeArguments& function_type_arguments =
583 TypeArguments::CheckedHandle(zone, arguments.ArgAt(3));
584 const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(4));
535 const SubtypeTestCache& cache = 585 const SubtypeTestCache& cache =
536 SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(4)); 586 SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(5));
537 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator. 587 ASSERT(!dst_type.IsMalformed()); // Already checked in code generator.
538 ASSERT(!dst_type.IsMalbounded()); // Already checked in code generator. 588 ASSERT(!dst_type.IsMalbounded()); // Already checked in code generator.
539 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment. 589 ASSERT(!dst_type.IsDynamicType()); // No need to check assignment.
540 ASSERT(!src_instance.IsNull()); // Already checked in inlined code. 590 ASSERT(!src_instance.IsNull()); // Already checked in inlined code.
541 591
542 Error& bound_error = Error::Handle(zone); 592 Error& bound_error = Error::Handle(zone);
543 const bool is_instance_of = src_instance.IsInstanceOf( 593 const bool is_instance_of =
544 dst_type, instantiator_type_arguments, &bound_error); 594 src_instance.IsInstanceOf(dst_type, instantiator_type_arguments,
595 function_type_arguments, &bound_error);
545 596
546 if (FLAG_trace_type_checks) { 597 if (FLAG_trace_type_checks) {
547 PrintTypeCheck("TypeCheck", src_instance, dst_type, 598 PrintTypeCheck("TypeCheck", src_instance, dst_type,
548 instantiator_type_arguments, Bool::Get(is_instance_of)); 599 instantiator_type_arguments, function_type_arguments,
600 Bool::Get(is_instance_of));
549 } 601 }
550 if (!is_instance_of) { 602 if (!is_instance_of) {
551 // Throw a dynamic type error. 603 // Throw a dynamic type error.
552 const TokenPosition location = GetCallerLocation(); 604 const TokenPosition location = GetCallerLocation();
553 const AbstractType& src_type = 605 const AbstractType& src_type =
554 AbstractType::Handle(zone, src_instance.GetType(Heap::kNew)); 606 AbstractType::Handle(zone, src_instance.GetType(Heap::kNew));
555 if (!dst_type.IsInstantiated()) { 607 if (!dst_type.IsInstantiated()) {
556 // Instantiate dst_type before reporting the error. 608 // Instantiate dst_type before reporting the error.
557 dst_type = dst_type.InstantiateFrom(instantiator_type_arguments, NULL, 609 dst_type = dst_type.InstantiateFrom(instantiator_type_arguments,
558 NULL, NULL, Heap::kNew); 610 function_type_arguments, NULL, NULL,
611 NULL, Heap::kNew);
559 // Note that instantiated dst_type may be malbounded. 612 // Note that instantiated dst_type may be malbounded.
560 } 613 }
561 String& bound_error_message = String::Handle(zone); 614 String& bound_error_message = String::Handle(zone);
562 if (!bound_error.IsNull()) { 615 if (!bound_error.IsNull()) {
563 ASSERT(isolate->type_checks()); 616 ASSERT(isolate->type_checks());
564 bound_error_message = String::New(bound_error.ToErrorCString()); 617 bound_error_message = String::New(bound_error.ToErrorCString());
565 } 618 }
566 Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name, 619 Exceptions::CreateAndThrowTypeError(location, src_type, dst_type, dst_name,
567 bound_error_message); 620 bound_error_message);
568 UNREACHABLE(); 621 UNREACHABLE();
569 } 622 }
570 UpdateTypeTestCache(src_instance, dst_type, instantiator_type_arguments, 623 UpdateTypeTestCache(src_instance, dst_type, instantiator_type_arguments,
571 Bool::True(), cache); 624 function_type_arguments, Bool::True(), cache);
572 arguments.SetReturn(src_instance); 625 arguments.SetReturn(src_instance);
573 } 626 }
574 627
575 628
576 // Report that the type of the given object is not bool in conditional context. 629 // Report that the type of the given object is not bool in conditional context.
577 // Throw assertion error if the object is null. (cf. Boolean Conversion 630 // Throw assertion error if the object is null. (cf. Boolean Conversion
578 // in language Spec.) 631 // in language Spec.)
579 // Arg0: bad object. 632 // Arg0: bad object.
580 // Return value: none, throws TypeError or AssertionError. 633 // Return value: none, throws TypeError or AssertionError.
581 DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) { 634 DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) {
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers); 852 ASSERT(!result.IsNull() || !FLAG_lazy_dispatchers);
800 return result.raw(); 853 return result.raw();
801 } 854 }
802 855
803 856
804 // Perform the subtype and return constant function based on the result. 857 // Perform the subtype and return constant function based on the result.
805 static RawFunction* ComputeTypeCheckTarget(const Instance& receiver, 858 static RawFunction* ComputeTypeCheckTarget(const Instance& receiver,
806 const AbstractType& type, 859 const AbstractType& type,
807 const ArgumentsDescriptor& desc) { 860 const ArgumentsDescriptor& desc) {
808 Error& error = Error::Handle(); 861 Error& error = Error::Handle();
809 bool result = 862 bool result = receiver.IsInstanceOf(type, Object::null_type_arguments(),
810 receiver.IsInstanceOf(type, Object::null_type_arguments(), &error); 863 Object::null_type_arguments(), &error);
811 ASSERT(error.IsNull()); 864 ASSERT(error.IsNull());
812 ObjectStore* store = Isolate::Current()->object_store(); 865 ObjectStore* store = Isolate::Current()->object_store();
813 const Function& target = 866 const Function& target =
814 Function::Handle(result ? store->simple_instance_of_true_function() 867 Function::Handle(result ? store->simple_instance_of_true_function()
815 : store->simple_instance_of_false_function()); 868 : store->simple_instance_of_false_function());
816 ASSERT(!target.IsNull()); 869 ASSERT(!target.IsNull());
817 return target.raw(); 870 return target.raw();
818 } 871 }
819 872
820 873
(...skipping 1398 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 const intptr_t elm_size = old_data.ElementSizeInBytes(); 2272 const intptr_t elm_size = old_data.ElementSizeInBytes();
2220 const TypedData& new_data = 2273 const TypedData& new_data =
2221 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 2274 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
2222 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 2275 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
2223 typed_data_cell.SetAt(0, new_data); 2276 typed_data_cell.SetAt(0, new_data);
2224 arguments.SetReturn(new_data); 2277 arguments.SetReturn(new_data);
2225 } 2278 }
2226 2279
2227 2280
2228 } // namespace dart 2281 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/class_finalizer.cc ('k') | runtime/vm/constant_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698