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

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

Issue 10021070: Move type check elimination from backend to graph builder in new compiler. (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 | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intermediate_language.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/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 122 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
123 __ CompareObject(RCX, *CoreClass("ObjectArray")); 123 __ CompareObject(RCX, *CoreClass("ObjectArray"));
124 __ j(EQUAL, is_instance); 124 __ j(EQUAL, is_instance);
125 __ CompareObject(RCX, *CoreClass("GrowableObjectArray")); 125 __ CompareObject(RCX, *CoreClass("GrowableObjectArray"));
126 __ j(EQUAL, is_instance); 126 __ j(EQUAL, is_instance);
127 } else if (!type_class.is_interface()) { 127 } else if (!type_class.is_interface()) {
128 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 128 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
129 __ CompareObject(RCX, type_class); 129 __ CompareObject(RCX, type_class);
130 __ j(EQUAL, is_instance); 130 __ j(EQUAL, is_instance);
131 } 131 }
132 // Fall through to runtime class. 132 // Fall through to runtime call.
133 } 133 }
134 } else { // type has NO type arguments. 134 } else { // type has NO type arguments.
135 Label compare_classes; 135 Label compare_classes;
136 __ testq(RAX, Immediate(kSmiTagMask)); 136 __ testq(RAX, Immediate(kSmiTagMask));
137 __ j(NOT_ZERO, &compare_classes); 137 __ j(NOT_ZERO, &compare_classes);
138 // Object is Smi. 138 // Object is Smi.
139 const Class& smi_class = Class::Handle(Smi::Class()); 139 const Class& smi_class = Class::Handle(Smi::Class());
140 // TODO(regis): We should introduce a SmiType. 140 // TODO(regis): We should introduce a SmiType.
141 Error& malformed_error = Error::Handle(); 141 Error& malformed_error = Error::Handle();
142 if (smi_class.IsSubtypeOf(TypeArguments::Handle(), 142 if (smi_class.IsSubtypeOf(TypeArguments::Handle(),
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // - RAX: object. 288 // - RAX: object.
289 // - RDX: optional instantiator type arguments. 289 // - RDX: optional instantiator type arguments.
290 // Destroys RCX and RDX. 290 // Destroys RCX and RDX.
291 // Returns: 291 // Returns:
292 // - object in RAX for successful assignable check (or throws TypeError). 292 // - object in RAX for successful assignable check (or throws TypeError).
293 // Performance notes: positive checks must be quick, negative checks can be slow 293 // Performance notes: positive checks must be quick, negative checks can be slow
294 // as they throw an exception. 294 // as they throw an exception.
295 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t node_id, 295 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t node_id,
296 intptr_t token_index, 296 intptr_t token_index,
297 intptr_t try_index, 297 intptr_t try_index,
298 Value* value,
299 const AbstractType& dst_type, 298 const AbstractType& dst_type,
300 const String& dst_name) { 299 const String& dst_name) {
301 ASSERT(FLAG_enable_type_checks); 300 ASSERT(FLAG_enable_type_checks);
302 ASSERT(token_index >= 0); 301 ASSERT(token_index >= 0);
303 ASSERT(!dst_type.IsNull()); 302 ASSERT(!dst_type.IsNull());
304 ASSERT(dst_type.IsFinalized()); 303 ASSERT(dst_type.IsFinalized());
305 304 ASSERT(dst_type.IsMalformed() ||
306 // Any expression is assignable to the Dynamic type and to the Object type. 305 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
307 // Skip the test. 306 ASSERT(!dst_type.IsVoidType());
308 if (!dst_type.IsMalformed() &&
309 (dst_type.IsDynamicType() || dst_type.IsObjectType())) {
310 return;
311 }
312
313 // It is a compile-time error to explicitly return a value (including null)
314 // from a void function. However, functions that do not explicitly return a
315 // value, implicitly return null. This includes void functions. Therefore, we
316 // skip the type test here and trust the parser to only return null in void
317 // function.
318 if (dst_type.IsVoidType()) {
319 return;
320 }
321
322 // TODO(regis): Move this compile time check to the graph builder.
323 // Eliminate the test if it can be performed successfully at compile time.
324 if ((value != NULL) && value->IsConstant()) {
325 Instance& literal_value = Instance::Handle();
326 literal_value ^= value->AsConstant()->value().raw();
327 const Class& cls = Class::Handle(literal_value.clazz());
328 if (cls.IsNullClass()) {
329 ASSERT(literal_value.IsNull() ||
330 (literal_value.raw() == Object::sentinel()) ||
331 (literal_value.raw() == Object::transition_sentinel()));
332 return;
333 }
334 Error& malformed_error = Error::Handle();
335 if (!dst_type.IsMalformed() &&
336 dst_type.IsInstantiated() &&
337 literal_value.IsInstanceOf(dst_type,
338 TypeArguments::Handle(),
339 &malformed_error)) {
340 return;
341 }
342 }
343 307
344 // A null object is always assignable and is returned as result. 308 // A null object is always assignable and is returned as result.
345 const Immediate raw_null = 309 const Immediate raw_null =
346 Immediate(reinterpret_cast<intptr_t>(Object::null())); 310 Immediate(reinterpret_cast<intptr_t>(Object::null()));
347 Label is_assignable, runtime_call; 311 Label is_assignable, runtime_call;
348 __ cmpq(RAX, raw_null); 312 __ cmpq(RAX, raw_null);
349 __ j(EQUAL, &is_assignable); 313 __ j(EQUAL, &is_assignable);
350 314
351 // Generate throw new TypeError() if the type is malformed. 315 // Generate throw new TypeError() if the type is malformed.
352 if (dst_type.IsMalformed()) { 316 if (dst_type.IsMalformed()) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 LoadValue(RAX, val); 384 LoadValue(RAX, val);
421 } 385 }
422 386
423 387
424 void FlowGraphCompiler::VisitConstant(ConstantVal* val) { 388 void FlowGraphCompiler::VisitConstant(ConstantVal* val) {
425 LoadValue(RAX, val); 389 LoadValue(RAX, val);
426 } 390 }
427 391
428 392
429 void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) { 393 void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) {
430 if (comp->type_arguments() != NULL) { 394 if (comp->instantiator_type_arguments() != NULL) {
431 __ popq(RDX); 395 __ popq(RDX);
432 } 396 }
433 LoadValue(RAX, comp->value()); 397 LoadValue(RAX, comp->value());
434 GenerateAssertAssignable(comp->node_id(), 398 GenerateAssertAssignable(comp->node_id(),
435 comp->token_index(), 399 comp->token_index(),
436 comp->try_index(), 400 comp->try_index(),
437 comp->value(),
438 comp->dst_type(), 401 comp->dst_type(),
439 comp->dst_name()); 402 comp->dst_name());
440 } 403 }
441 404
442 405
443 void FlowGraphCompiler::VisitAssertBoolean(AssertBooleanComp* comp) { 406 void FlowGraphCompiler::VisitAssertBoolean(AssertBooleanComp* comp) {
444 LoadValue(RAX, comp->value()); 407 LoadValue(RAX, comp->value());
445 // Check that the type of the value is allowed in conditional context. 408 // Check that the type of the value is allowed in conditional context.
446 // Call the runtime if the object is not bool::true or bool::false. 409 // Call the runtime if the object is not bool::true or bool::false.
447 Label done; 410 Label done;
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 // - Class equality (only if class is not parameterized). 796 // - Class equality (only if class is not parameterized).
834 // Inputs: 797 // Inputs:
835 // - RAX: object. 798 // - RAX: object.
836 // - RDX: optional instantiator type arguments. 799 // - RDX: optional instantiator type arguments.
837 // Destroys RCX and RDX. 800 // Destroys RCX and RDX.
838 // Returns: 801 // Returns:
839 // - true or false in RAX. 802 // - true or false in RAX.
840 void FlowGraphCompiler::GenerateInstanceOf(intptr_t node_id, 803 void FlowGraphCompiler::GenerateInstanceOf(intptr_t node_id,
841 intptr_t token_index, 804 intptr_t token_index,
842 intptr_t try_index, 805 intptr_t try_index,
843 Value* value,
844 const AbstractType& type, 806 const AbstractType& type,
845 bool negate_result) { 807 bool negate_result) {
846 ASSERT(type.IsFinalized() && !type.IsMalformed()); 808 ASSERT(type.IsFinalized() && !type.IsMalformed());
847 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 809 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
848 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 810 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
849 811
850 const Immediate raw_null = 812 const Immediate raw_null =
851 Immediate(reinterpret_cast<intptr_t>(Object::null())); 813 Immediate(reinterpret_cast<intptr_t>(Object::null()));
852 Label is_instance, is_not_instance; 814 Label is_instance, is_not_instance;
853 // If type is instantiated and non-parameterized, we can inline code 815 // If type is instantiated and non-parameterized, we can inline code
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 871
910 872
911 void FlowGraphCompiler::VisitInstanceOf(InstanceOfComp* comp) { 873 void FlowGraphCompiler::VisitInstanceOf(InstanceOfComp* comp) {
912 if (comp->type_arguments() != NULL) { 874 if (comp->type_arguments() != NULL) {
913 __ popq(RDX); 875 __ popq(RDX);
914 } 876 }
915 LoadValue(RAX, comp->value()); 877 LoadValue(RAX, comp->value());
916 GenerateInstanceOf(comp->node_id(), 878 GenerateInstanceOf(comp->node_id(),
917 comp->token_index(), 879 comp->token_index(),
918 comp->try_index(), 880 comp->try_index(),
919 comp->value(),
920 comp->type(), 881 comp->type(),
921 comp->negate_result()); 882 comp->negate_result());
922 } 883 }
923 884
924 885
925 void FlowGraphCompiler::VisitAllocateObject(AllocateObjectComp* comp) { 886 void FlowGraphCompiler::VisitAllocateObject(AllocateObjectComp* comp) {
926 const Class& cls = Class::ZoneHandle(comp->constructor().owner()); 887 const Class& cls = Class::ZoneHandle(comp->constructor().owner());
927 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls)); 888 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
928 const ExternalLabel label(cls.ToCString(), stub.EntryPoint()); 889 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
929 GenerateCall(comp->token_index(), comp->try_index(), &label, 890 GenerateCall(comp->token_index(), comp->try_index(), &label,
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 ASSERT(exception_handlers_list_ != NULL); 1711 ASSERT(exception_handlers_list_ != NULL);
1751 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( 1712 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
1752 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); 1713 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
1753 code.set_exception_handlers(handlers); 1714 code.set_exception_handlers(handlers);
1754 } 1715 }
1755 1716
1756 1717
1757 } // namespace dart 1718 } // namespace dart
1758 1719
1759 #endif // defined TARGET_ARCH_X64 1720 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698