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

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

Issue 9939003: Use null type argument vector instead of vector of Dynamic for a generic raw (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
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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 } 767 }
768 } else { 768 } else {
769 // Pop the previously evaluated result value into EAX. 769 // Pop the previously evaluated result value into EAX.
770 __ popl(EAX); 770 __ popl(EAX);
771 } 771 }
772 772
773 // Generate type check. 773 // Generate type check.
774 if (FLAG_enable_type_checks) { 774 if (FLAG_enable_type_checks) {
775 const bool returns_null = node->value()->IsLiteralNode() && 775 const bool returns_null = node->value()->IsLiteralNode() &&
776 node->value()->AsLiteralNode()->literal().IsNull(); 776 node->value()->AsLiteralNode()->literal().IsNull();
777 const RawFunction::Kind kind = parsed_function().function().kind(); 777 const RawFunction::Kind kind = parsed_function().function().kind();
778 // Implicit getters do not need a type check at return. 778 // Implicit getters do not need a type check at return.
779 if (!returns_null && 779 if (!returns_null &&
780 (kind != RawFunction::kImplicitGetter) && 780 (kind != RawFunction::kImplicitGetter) &&
781 (kind != RawFunction::kConstImplicitGetter)) { 781 (kind != RawFunction::kConstImplicitGetter)) {
782 GenerateAssertAssignable( 782 GenerateAssertAssignable(
783 node->id(), 783 node->id(),
784 node->value()->token_index(), 784 node->value()->token_index(),
785 AbstractType::ZoneHandle(parsed_function().function().result_type()), 785 AbstractType::ZoneHandle(parsed_function().function().result_type()),
786 String::ZoneHandle(String::NewSymbol("function result"))); 786 String::ZoneHandle(String::NewSymbol("function result")));
787 } 787 }
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 1381
1382 const Class& type_class = Class::ZoneHandle(type.type_class()); 1382 const Class& type_class = Class::ZoneHandle(type.type_class());
1383 const bool requires_type_arguments = type_class.HasTypeArguments(); 1383 const bool requires_type_arguments = type_class.HasTypeArguments();
1384 // A Smi object cannot be the instance of a parameterized class. 1384 // A Smi object cannot be the instance of a parameterized class.
1385 // A class equality check is only applicable with a dst type of a 1385 // A class equality check is only applicable with a dst type of a
1386 // non-parameterized class or with a raw dst type of a parameterized class. 1386 // non-parameterized class or with a raw dst type of a parameterized class.
1387 if (requires_type_arguments) { 1387 if (requires_type_arguments) {
1388 const AbstractTypeArguments& type_arguments = 1388 const AbstractTypeArguments& type_arguments =
1389 AbstractTypeArguments::Handle(type.arguments()); 1389 AbstractTypeArguments::Handle(type.arguments());
1390 const bool is_raw_type = type_arguments.IsNull() || 1390 const bool is_raw_type = type_arguments.IsNull() ||
1391 type_arguments.IsDynamicTypes(type_arguments.Length()); 1391 type_arguments.IsRaw(type_arguments.Length());
1392 Label runtime_call; 1392 Label runtime_call;
1393 __ testl(EAX, Immediate(kSmiTagMask)); 1393 __ testl(EAX, Immediate(kSmiTagMask));
1394 __ j(ZERO, &runtime_call, Assembler::kNearJump); 1394 __ j(ZERO, &runtime_call, Assembler::kNearJump);
1395 // Object not Smi. 1395 // Object not Smi.
1396 if (is_raw_type) { 1396 if (is_raw_type) {
1397 if (type.IsListInterface()) { 1397 if (type.IsListInterface()) {
1398 Label push_result; 1398 Label push_result;
1399 // TODO(srdjan) also accept List<Object>. 1399 // TODO(srdjan) also accept List<Object>.
1400 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1400 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1401 __ CompareObject(ECX, *CoreClass("ObjectArray")); 1401 __ CompareObject(ECX, *CoreClass("ObjectArray"));
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 if (dst_type.IsInstantiated()) { 1562 if (dst_type.IsInstantiated()) {
1563 const Class& dst_type_class = Class::ZoneHandle(dst_type.type_class()); 1563 const Class& dst_type_class = Class::ZoneHandle(dst_type.type_class());
1564 const bool dst_class_has_type_arguments = dst_type_class.HasTypeArguments(); 1564 const bool dst_class_has_type_arguments = dst_type_class.HasTypeArguments();
1565 // A Smi object cannot be the instance of a parameterized class. 1565 // A Smi object cannot be the instance of a parameterized class.
1566 // A class equality check is only applicable with a dst type of a 1566 // A class equality check is only applicable with a dst type of a
1567 // non-parameterized class or with a raw dst type of a parameterized class. 1567 // non-parameterized class or with a raw dst type of a parameterized class.
1568 if (dst_class_has_type_arguments) { 1568 if (dst_class_has_type_arguments) {
1569 const AbstractTypeArguments& dst_type_arguments = 1569 const AbstractTypeArguments& dst_type_arguments =
1570 AbstractTypeArguments::Handle(dst_type.arguments()); 1570 AbstractTypeArguments::Handle(dst_type.arguments());
1571 const bool is_raw_dst_type = dst_type_arguments.IsNull() || 1571 const bool is_raw_dst_type = dst_type_arguments.IsNull() ||
1572 dst_type_arguments.IsDynamicTypes(dst_type_arguments.Length()); 1572 dst_type_arguments.IsRaw(dst_type_arguments.Length());
1573 if (is_raw_dst_type) { 1573 if (is_raw_dst_type) {
1574 // Dynamic type argument, check only classes. 1574 // Dynamic type argument, check only classes.
1575 if (dst_type.IsListInterface()) { 1575 if (dst_type.IsListInterface()) {
1576 // TODO(srdjan) also accept List<Object>. 1576 // TODO(srdjan) also accept List<Object>.
1577 __ testl(EAX, Immediate(kSmiTagMask)); 1577 __ testl(EAX, Immediate(kSmiTagMask));
1578 __ j(ZERO, &runtime_call, Assembler::kNearJump); 1578 __ j(ZERO, &runtime_call, Assembler::kNearJump);
1579 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1579 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1580 TestClassAndJump(*CoreClass("ObjectArray"), &done); 1580 TestClassAndJump(*CoreClass("ObjectArray"), &done);
1581 TestClassAndJump(*CoreClass("GrowableObjectArray"), &done); 1581 TestClassAndJump(*CoreClass("GrowableObjectArray"), &done);
1582 } else if (!dst_type_class.is_interface()) { 1582 } else if (!dst_type_class.is_interface()) {
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after
2389 bool requires_type_arguments) { 2389 bool requires_type_arguments) {
2390 const Immediate raw_null = 2390 const Immediate raw_null =
2391 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2391 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2392 // Instantiate the type arguments if necessary. 2392 // Instantiate the type arguments if necessary.
2393 if (node->type_arguments().IsNull() || 2393 if (node->type_arguments().IsNull() ||
2394 node->type_arguments().IsInstantiated()) { 2394 node->type_arguments().IsInstantiated()) {
2395 if (requires_type_arguments) { 2395 if (requires_type_arguments) {
2396 // A factory requires the type arguments as first parameter. 2396 // A factory requires the type arguments as first parameter.
2397 __ PushObject(node->type_arguments()); 2397 __ PushObject(node->type_arguments());
2398 if (!node->constructor().IsFactory()) { 2398 if (!node->constructor().IsFactory()) {
2399 // The allocator additionally requires the instantiator type arguments. 2399 // The non-factory allocator additionally requires the instantiator
2400 __ pushl(raw_null); // Null instantiator. 2400 // type arguments which are not needed here, since the type arguments
2401 // are instantiated.
2402 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2401 } 2403 }
2402 } 2404 }
2403 } else { 2405 } else {
2404 // The type arguments are uninstantiated. 2406 // The type arguments are uninstantiated.
2405 ASSERT(requires_type_arguments); 2407 ASSERT(requires_type_arguments);
2406 GenerateInstantiatorTypeArguments(node->token_index()); 2408 GenerateInstantiatorTypeArguments(node->token_index());
2407 __ popl(EAX); // Pop instantiator. 2409 __ popl(EAX); // Pop instantiator.
2408 // EAX is the instantiator AbstractTypeArguments object (or null). 2410 // EAX is the instantiator AbstractTypeArguments object (or null).
2409 // If EAX is null, no need to instantiate the type arguments, use null, and 2411 // If the instantiator is null and if the type argument vector
2410 // allocate an object of a raw type. 2412 // instantiated from null becomes a vector of Dynamic, then use null as
2411 Label type_arguments_instantiated, type_arguments_uninstantiated; 2413 // the type arguments.
2412 __ cmpl(EAX, raw_null); 2414 Label type_arguments_instantiated;
2413 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2415 const intptr_t len = node->type_arguments().Length();
2414 2416 if (node->type_arguments().IsRawInstantiatedRaw(len)) {
2417 __ cmpl(EAX, raw_null);
2418 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2419 }
2415 // Instantiate non-null type arguments. 2420 // Instantiate non-null type arguments.
2416 if (node->type_arguments().IsUninstantiatedIdentity()) { 2421 if (node->type_arguments().IsUninstantiatedIdentity()) {
2417 // Check if the instantiator type argument vector is a TypeArguments of a 2422 // Check if the instantiator type argument vector is a TypeArguments of a
2418 // matching length and, if so, use it as the instantiated type_arguments. 2423 // matching length and, if so, use it as the instantiated type_arguments.
2424 // No need to check RAX for null (again), because a null instance will
2425 // have the wrong class (Null instead of TypeArguments).
2426 Label type_arguments_uninstantiated;
2419 __ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class())); 2427 __ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class()));
2420 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset())); 2428 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset()));
2421 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 2429 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
2422 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>( 2430 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>(
2423 Smi::New(node->type_arguments().Length()))); 2431 Smi::New(node->type_arguments().Length())));
2424 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()), 2432 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()),
2425 arguments_length); 2433 arguments_length);
2426 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2434 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2435 __ Bind(&type_arguments_uninstantiated);
2427 } 2436 }
2428 __ Bind(&type_arguments_uninstantiated);
2429 if (node->constructor().IsFactory()) { 2437 if (node->constructor().IsFactory()) {
2430 // A runtime call to instantiate the type arguments is required before 2438 // A runtime call to instantiate the type arguments is required before
2431 // calling the factory. 2439 // calling the factory.
2432 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2440 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2433 __ PushObject(node->type_arguments()); 2441 __ PushObject(node->type_arguments());
2434 __ pushl(EAX); // Push instantiator type arguments. 2442 __ pushl(EAX); // Push instantiator type arguments.
2435 GenerateCallRuntime(node->id(), 2443 GenerateCallRuntime(node->id(),
2436 node->token_index(), 2444 node->token_index(),
2437 kInstantiateTypeArgumentsRuntimeEntry); 2445 kInstantiateTypeArgumentsRuntimeEntry);
2438 __ popl(EAX); // Pop instantiator type arguments. 2446 __ popl(EAX); // Pop instantiator type arguments.
2439 __ popl(EAX); // Pop uninstantiated type arguments. 2447 __ popl(EAX); // Pop uninstantiated type arguments.
2440 __ popl(EAX); // Pop instantiated type arguments. 2448 __ popl(EAX); // Pop instantiated type arguments.
2441 __ Bind(&type_arguments_instantiated); 2449 __ Bind(&type_arguments_instantiated);
2442 __ pushl(EAX); // Instantiated type arguments. 2450 __ pushl(EAX); // Instantiated type arguments.
2443 } else { 2451 } else {
2444 // In the non-factory case, we rely on the allocation stub to 2452 // In the non-factory case, we rely on the allocation stub to
2445 // instantiate the type arguments. 2453 // instantiate the type arguments.
2446 __ PushObject(node->type_arguments()); 2454 __ PushObject(node->type_arguments());
2447 __ pushl(EAX); // Instantiator type arguments. 2455 __ pushl(EAX); // Instantiator type arguments.
2448 Label type_arguments_pushed; 2456 Label type_arguments_pushed;
2449 __ jmp(&type_arguments_pushed, Assembler::kNearJump); 2457 __ jmp(&type_arguments_pushed, Assembler::kNearJump);
2450 2458
2451 __ Bind(&type_arguments_instantiated); 2459 __ Bind(&type_arguments_instantiated);
2452 __ pushl(EAX); // Instantiated type arguments. 2460 __ pushl(EAX); // Instantiated type arguments.
2453 __ pushl(raw_null); // Null instantiator. 2461 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2454 __ Bind(&type_arguments_pushed); 2462 __ Bind(&type_arguments_pushed);
2455 } 2463 }
2456 } 2464 }
2457 } 2465 }
2458 2466
2459 2467
2460 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) { 2468 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) {
2461 if (node->constructor().IsFactory()) { 2469 if (node->constructor().IsFactory()) {
2462 const bool requires_type_arguments = true; // Always first arg to factory. 2470 const bool requires_type_arguments = true; // Always first arg to factory.
2463 GenerateTypeArguments(node, requires_type_arguments); 2471 GenerateTypeArguments(node, requires_type_arguments);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 } 2503 }
2496 2504
2497 if (IsResultNeeded(node)) { 2505 if (IsResultNeeded(node)) {
2498 __ pushl(EAX); // Set up return value from allocate. 2506 __ pushl(EAX); // Set up return value from allocate.
2499 } 2507 }
2500 2508
2501 // First argument(this) for constructor call which follows. 2509 // First argument(this) for constructor call which follows.
2502 __ pushl(EAX); 2510 __ pushl(EAX);
2503 // Second argument is the implicit construction phase parameter. 2511 // Second argument is the implicit construction phase parameter.
2504 // Run both the constructor initializer list and the constructor body. 2512 // Run both the constructor initializer list and the constructor body.
2505 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 2513 __ pushl(Immediate(Smi::RawValue(Function::kCtorPhaseAll)));
2506
2507 2514
2508 // Now setup rest of the arguments for the constructor call. 2515 // Now setup rest of the arguments for the constructor call.
2509 node->arguments()->Visit(this); 2516 node->arguments()->Visit(this);
2510 2517
2511 // Call the constructor. 2518 // Call the constructor.
2512 // +2 to include implicit receiver and phase arguments. 2519 // +2 to include implicit receiver and phase arguments.
2513 int num_args = node->arguments()->length() + 2; 2520 int num_args = node->arguments()->length() + 2;
2514 __ LoadObject(ECX, node->constructor()); 2521 __ LoadObject(ECX, node->constructor());
2515 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names())); 2522 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names()));
2516 GenerateCall(node->token_index(), 2523 GenerateCall(node->token_index(),
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2837 const Error& error = Error::Handle( 2844 const Error& error = Error::Handle(
2838 Parser::FormatError(script, token_index, "Error", format, args)); 2845 Parser::FormatError(script, token_index, "Error", format, args));
2839 va_end(args); 2846 va_end(args);
2840 Isolate::Current()->long_jump_base()->Jump(1, error); 2847 Isolate::Current()->long_jump_base()->Jump(1, error);
2841 UNREACHABLE(); 2848 UNREACHABLE();
2842 } 2849 }
2843 2850
2844 } // namespace dart 2851 } // namespace dart
2845 2852
2846 #endif // defined TARGET_ARCH_IA32 2853 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698