Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler_x64.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_compiler_x64.cc (revision 6416) |
| +++ runtime/vm/flow_graph_compiler_x64.cc (working copy) |
| @@ -449,7 +449,8 @@ |
| // Copied from CodeGenerator. |
| -// Optimize instanceof type test by adding inlined tests for: |
| +// If instanceof type test cannot be performed successfully at compile time and |
| +// therefore eliminated, optimize it by adding inlined tests for: |
| // - NULL -> return false. |
| // - Smi -> compile time subtype check (only if dst class is not parameterized). |
| // - Class equality (only if class is not parameterized). |
| @@ -461,13 +462,14 @@ |
| void FlowGraphCompiler::GenerateInstanceOf(intptr_t node_id, |
| intptr_t token_index, |
| intptr_t try_index, |
| + Value* value, |
| const AbstractType& type, |
| bool negate_result) { |
| ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| - // All instances are of a subtype of the Object type. |
| + // All objects are instances of type T if Object type is a subtype of type T. |
| const Type& object_type = |
| Type::Handle(Isolate::Current()->object_store()->object_type()); |
| Error& malformed_error = Error::Handle(); |
| @@ -477,6 +479,32 @@ |
| return; |
| } |
| + // Eliminate the test if it can be performed successfully at compile time. |
| + if ((value != NULL) && value->IsConstant() && type.IsInstantiated()) { |
| + // TODO(regis): A constant value should be an instance, not an object. |
| + Instance& literal_value = Instance::Handle(); |
| + literal_value ^= value->AsConstant()->value().raw(); |
| + const Class& cls = Class::Handle(literal_value.clazz()); |
| + if (cls.IsNullClass()) { |
| + ASSERT(literal_value.IsNull() || |
| + (literal_value.raw() == Object::sentinel()) || |
| + (literal_value.raw() == Object::transition_sentinel())); |
| + // A null object is only an instance of Object and Dynamic, which has |
| + // already been checked above (if the type is instantiated). So we can |
| + // return false here if the instance is null (and if the type is |
| + // instantiated). |
| + __ PushObject(negate_result ? bool_true : bool_false); |
| + return; |
| + } |
| + Error& malformed_error = Error::Handle(); |
| + if (literal_value.IsInstanceOf(type, |
| + TypeArguments::Handle(), |
| + &malformed_error)) { |
| + __ PushObject(negate_result ? bool_false : bool_true); |
| + return; |
| + } |
|
srdjan
2012/04/11 17:25:08
ditto (missing an else)
regis
2012/04/11 17:42:12
Done.
|
| + } |
| + |
| const Immediate raw_null = |
| Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| Label done; |
| @@ -535,6 +563,8 @@ |
| __ Bind(&runtime_call); |
| // Fall through to runtime call. |
| } else { |
| + ASSERT(!requires_type_arguments); |
| + // Test if object is Smi and for a couple known test-classes. |
| Label compare_classes; |
| __ testq(RAX, Immediate(kSmiTagMask)); |
| __ j(NOT_ZERO, &compare_classes, Assembler::kNearJump); |
| @@ -613,6 +643,7 @@ |
| GenerateInstanceOf(comp->node_id(), |
| comp->token_index(), |
| comp->try_index(), |
| + comp->value(), |
| comp->type(), |
| comp->negate_result()); |
| } |