Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/object.h" | 8 #include "vm/object.h" |
| 9 #include "vm/os.h" | 9 #include "vm/os.h" |
| 10 #include "vm/scopes.h" | 10 #include "vm/scopes.h" |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 // nonoptimizing compiler. | 281 // nonoptimizing compiler. |
| 282 ASSERT(true_successor_ != NULL); | 282 ASSERT(true_successor_ != NULL); |
| 283 ASSERT(false_successor_ != NULL); | 283 ASSERT(false_successor_ != NULL); |
| 284 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent, | 284 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent, |
| 285 assigned_vars, variable_count); | 285 assigned_vars, variable_count); |
| 286 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent, | 286 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent, |
| 287 assigned_vars, variable_count); | 287 assigned_vars, variable_count); |
| 288 } | 288 } |
| 289 | 289 |
| 290 | 290 |
| 291 // ==== Support for propagating static type. | |
| 292 RawAbstractType* ConstantVal::StaticType() const { | |
| 293 if (value().IsInstance()) { | |
| 294 Instance& instance = Instance::Handle(); | |
| 295 instance ^= value().raw(); | |
| 296 return instance.GetType(); | |
| 297 } else { | |
| 298 UNREACHABLE(); | |
| 299 return Type::VoidType(); | |
| 300 } | |
| 301 } | |
| 302 | |
| 303 | |
| 304 RawAbstractType* UseVal::StaticType() const { | |
| 305 return definition()->StaticType(); | |
| 306 } | |
| 307 | |
| 308 | |
| 309 RawAbstractType* AssertAssignableComp::StaticType() const { | |
| 310 return dst_type().raw(); | |
| 311 } | |
| 312 | |
| 313 | |
| 314 RawAbstractType* AssertBooleanComp::StaticType() const { | |
| 315 return Type::BoolInterface(); | |
|
srdjan
2012/05/16 20:16:15
Bool class instead of interface type? It probably
regis
2012/05/16 23:20:37
Yes, I think it does not matter.
| |
| 316 } | |
| 317 | |
| 318 | |
| 319 RawAbstractType* CurrentContextComp::StaticType() const { | |
| 320 UNREACHABLE(); | |
|
srdjan
2012/05/16 20:16:15
Maybe it would be better to remove UNREACHABLE's a
regis
2012/05/16 23:20:37
As we discussed, I am now returning AbstractType::
| |
| 321 return Type::VoidType(); | |
| 322 } | |
| 323 | |
| 324 | |
| 325 RawAbstractType* StoreContextComp::StaticType() const { | |
| 326 UNREACHABLE(); | |
| 327 return Type::VoidType(); | |
| 328 } | |
| 329 | |
| 330 | |
| 331 RawAbstractType* ClosureCallComp::StaticType() const { | |
| 332 // The closure is the first argument to the call. | |
| 333 const AbstractType& function_type = | |
| 334 AbstractType::Handle(ArgumentAt(0)->StaticType()); | |
| 335 if (function_type.IsDynamicType() || function_type.IsFunctionInterface()) { | |
| 336 // The function type is not statically known or simply Function. | |
| 337 return Type::DynamicType(); | |
|
srdjan
2012/05/16 20:16:15
In the context of static type check elimination a
regis
2012/05/16 23:20:37
Correct.
| |
| 338 } | |
| 339 const Class& signature_class = Class::Handle(function_type.type_class()); | |
| 340 ASSERT(signature_class.IsSignatureClass()); | |
| 341 const Function& signature_function = | |
| 342 Function::Handle(signature_class.signature_function()); | |
| 343 // TODO(regis): The result type may be generic. | |
| 344 return signature_function.result_type(); | |
| 345 } | |
| 346 | |
| 347 | |
| 348 RawAbstractType* InstanceCallComp::StaticType() const { | |
| 349 return Type::DynamicType(); | |
| 350 } | |
| 351 | |
| 352 | |
| 353 RawAbstractType* StaticCallComp::StaticType() const { | |
| 354 return function().result_type(); | |
| 355 } | |
| 356 | |
| 357 | |
| 358 RawAbstractType* LoadLocalComp::StaticType() const { | |
| 359 return local().type().raw(); | |
| 360 } | |
| 361 | |
| 362 | |
| 363 RawAbstractType* StoreLocalComp::StaticType() const { | |
| 364 return value()->StaticType(); | |
|
srdjan
2012/05/16 20:16:15
If value()->StaticType() is Dynamic (unknown), the
regis
2012/05/16 23:20:37
Done.
| |
| 365 } | |
| 366 | |
| 367 | |
| 368 RawAbstractType* StrictCompareComp::StaticType() const { | |
| 369 return Type::BoolInterface(); | |
| 370 } | |
| 371 | |
| 372 | |
| 373 RawAbstractType* EqualityCompareComp::StaticType() const { | |
| 374 return Type::BoolInterface(); | |
| 375 } | |
| 376 | |
| 377 | |
| 378 RawAbstractType* NativeCallComp::StaticType() const { | |
| 379 // The result type of the native function is not known. | |
|
srdjan
2012/05/16 20:16:15
It could be probable computed, as it is known as c
regis
2012/05/16 23:20:37
It is actually the result type of the enclosing na
| |
| 380 return Type::DynamicType(); | |
| 381 } | |
| 382 | |
| 383 | |
| 384 RawAbstractType* StoreIndexedComp::StaticType() const { | |
| 385 return value()->StaticType(); | |
| 386 } | |
| 387 | |
| 388 | |
| 389 RawAbstractType* InstanceSetterComp::StaticType() const { | |
| 390 // TODO(regis): Would it be correct to return value()->StaticType()? | |
| 391 return Type::DynamicType(); | |
| 392 } | |
| 393 | |
| 394 | |
| 395 RawAbstractType* StaticSetterComp::StaticType() const { | |
| 396 // TODO(regis): Would it be correct/better to return value()->StaticType()? | |
| 397 return setter_function().result_type(); | |
| 398 } | |
| 399 | |
| 400 | |
| 401 RawAbstractType* LoadInstanceFieldComp::StaticType() const { | |
| 402 return field().type(); | |
| 403 } | |
| 404 | |
| 405 | |
| 406 RawAbstractType* StoreInstanceFieldComp::StaticType() const { | |
| 407 return value()->StaticType(); | |
|
srdjan
2012/05/16 20:16:15
And if value's type is unknown, return field's typ
regis
2012/05/16 23:20:37
Done.
| |
| 408 } | |
| 409 | |
| 410 | |
| 411 RawAbstractType* LoadStaticFieldComp::StaticType() const { | |
| 412 return field().type(); | |
| 413 } | |
| 414 | |
| 415 | |
| 416 RawAbstractType* StoreStaticFieldComp::StaticType() const { | |
| 417 return value()->StaticType(); | |
|
srdjan
2012/05/16 20:16:15
And if value's type is unknown, return field's typ
regis
2012/05/16 23:20:37
Done.
| |
| 418 } | |
| 419 | |
| 420 | |
| 421 RawAbstractType* BooleanNegateComp::StaticType() const { | |
| 422 return Type::BoolInterface(); | |
| 423 } | |
| 424 | |
| 425 | |
| 426 RawAbstractType* InstanceOfComp::StaticType() const { | |
| 427 return Type::BoolInterface(); | |
| 428 } | |
| 429 | |
| 430 | |
| 431 RawAbstractType* CreateArrayComp::StaticType() const { | |
| 432 UNREACHABLE(); | |
| 433 return Type::VoidType(); | |
| 434 } | |
| 435 | |
| 436 | |
| 437 RawAbstractType* CreateClosureComp::StaticType() const { | |
| 438 const Function& fun = function(); | |
| 439 const Class& signature_class = Class::Handle(fun.signature_class()); | |
| 440 // TODO(regis): Can we take (constant) type_arguments() into consideration? | |
| 441 // For now, we return Dynamic (no type test elimination) if the signature | |
| 442 // class is parameterized, or a non-parameterized finalized type otherwise. | |
| 443 if (signature_class.HasTypeArguments()) { | |
| 444 return Type::DynamicType(); | |
| 445 } | |
| 446 // Make sure we use the canonical signature class. | |
| 447 const Type& type = Type::Handle(signature_class.SignatureType()); | |
| 448 const Class& canonical_signature_class = Class::Handle(type.type_class()); | |
| 449 return Type::NewNonParameterizedType(canonical_signature_class); | |
| 450 } | |
| 451 | |
| 452 | |
| 453 RawAbstractType* AllocateObjectComp::StaticType() const { | |
| 454 UNREACHABLE(); | |
| 455 return Type::VoidType(); | |
|
srdjan
2012/05/16 20:16:15
For each UNREACHABLE, shouldn't return be DynamicT
regis
2012/05/16 23:20:37
As explained above, I want to catch wrong requests
| |
| 456 } | |
| 457 | |
| 458 | |
| 459 RawAbstractType* AllocateObjectWithBoundsCheckComp::StaticType() const { | |
| 460 UNREACHABLE(); | |
| 461 return Type::VoidType(); | |
| 462 } | |
| 463 | |
| 464 | |
| 465 RawAbstractType* NativeLoadFieldComp::StaticType() const { | |
| 466 ASSERT(!type().IsNull()); | |
| 467 return type().raw(); | |
| 468 } | |
| 469 | |
| 470 | |
| 471 RawAbstractType* NativeStoreFieldComp::StaticType() const { | |
| 472 return value()->StaticType(); | |
| 473 } | |
| 474 | |
| 475 | |
| 476 RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const { | |
| 477 UNREACHABLE(); | |
| 478 return Type::VoidType(); | |
| 479 } | |
| 480 | |
| 481 | |
| 482 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const { | |
| 483 UNREACHABLE(); | |
| 484 return Type::VoidType(); | |
| 485 } | |
| 486 | |
| 487 | |
| 488 RawAbstractType* ExtractConstructorInstantiatorComp::StaticType() const { | |
| 489 UNREACHABLE(); | |
| 490 return Type::VoidType(); | |
| 491 } | |
| 492 | |
| 493 | |
| 494 RawAbstractType* AllocateContextComp::StaticType() const { | |
| 495 UNREACHABLE(); | |
| 496 return Type::VoidType(); | |
| 497 } | |
| 498 | |
| 499 | |
| 500 RawAbstractType* ChainContextComp::StaticType() const { | |
| 501 UNREACHABLE(); | |
| 502 return Type::VoidType(); | |
| 503 } | |
| 504 | |
| 505 | |
| 506 RawAbstractType* CloneContextComp::StaticType() const { | |
| 507 UNREACHABLE(); | |
| 508 return Type::VoidType(); | |
| 509 } | |
| 510 | |
| 511 | |
| 512 RawAbstractType* CatchEntryComp::StaticType() const { | |
| 513 UNREACHABLE(); | |
| 514 return Type::VoidType(); | |
| 515 } | |
| 516 | |
| 517 | |
| 291 } // namespace dart | 518 } // namespace dart |
| OLD | NEW |