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

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
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/code_generator_x64.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) 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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 bool requires_type_arguments) { 2384 bool requires_type_arguments) {
2385 const Immediate raw_null = 2385 const Immediate raw_null =
2386 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2386 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2387 // Instantiate the type arguments if necessary. 2387 // Instantiate the type arguments if necessary.
2388 if (node->type_arguments().IsNull() || 2388 if (node->type_arguments().IsNull() ||
2389 node->type_arguments().IsInstantiated()) { 2389 node->type_arguments().IsInstantiated()) {
2390 if (requires_type_arguments) { 2390 if (requires_type_arguments) {
2391 // A factory requires the type arguments as first parameter. 2391 // A factory requires the type arguments as first parameter.
2392 __ PushObject(node->type_arguments()); 2392 __ PushObject(node->type_arguments());
2393 if (!node->constructor().IsFactory()) { 2393 if (!node->constructor().IsFactory()) {
2394 // The allocator additionally requires the instantiator type arguments. 2394 // The non-factory allocator additionally requires the instantiator
2395 __ pushl(raw_null); // Null instantiator. 2395 // type arguments which are not needed here, since the type arguments
2396 // are instantiated.
2397 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2396 } 2398 }
2397 } 2399 }
2398 } else { 2400 } else {
2399 // The type arguments are uninstantiated. 2401 // The type arguments are uninstantiated.
2400 ASSERT(requires_type_arguments); 2402 ASSERT(requires_type_arguments);
2401 GenerateInstantiatorTypeArguments(node->token_index()); 2403 GenerateInstantiatorTypeArguments(node->token_index());
2402 __ popl(EAX); // Pop instantiator. 2404 __ popl(EAX); // Pop instantiator.
2403 // EAX is the instantiator AbstractTypeArguments object (or null). 2405 // EAX is the instantiator AbstractTypeArguments object (or null).
2404 // If EAX is null, no need to instantiate the type arguments, use null, and 2406 // If the instantiator is null and if the type argument vector
2405 // allocate an object of a raw type. 2407 // instantiated from null becomes a vector of Dynamic, then use null as
2406 Label type_arguments_instantiated, type_arguments_uninstantiated; 2408 // the type arguments.
2407 __ cmpl(EAX, raw_null); 2409 Label type_arguments_instantiated;
2408 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2410 const intptr_t len = node->type_arguments().Length();
2409 2411 if (node->type_arguments().IsRawInstantiatedRaw(len)) {
2412 __ cmpl(EAX, raw_null);
2413 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2414 }
2410 // Instantiate non-null type arguments. 2415 // Instantiate non-null type arguments.
2411 if (node->type_arguments().IsUninstantiatedIdentity()) { 2416 if (node->type_arguments().IsUninstantiatedIdentity()) {
2412 // Check if the instantiator type argument vector is a TypeArguments of a 2417 // Check if the instantiator type argument vector is a TypeArguments of a
2413 // matching length and, if so, use it as the instantiated type_arguments. 2418 // matching length and, if so, use it as the instantiated type_arguments.
2419 // No need to check RAX for null (again), because a null instance will
2420 // have the wrong class (Null instead of TypeArguments).
2421 Label type_arguments_uninstantiated;
2414 __ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class())); 2422 __ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class()));
2415 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset())); 2423 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset()));
2416 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 2424 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
2417 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>( 2425 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>(
2418 Smi::New(node->type_arguments().Length()))); 2426 Smi::New(node->type_arguments().Length())));
2419 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()), 2427 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()),
2420 arguments_length); 2428 arguments_length);
2421 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2429 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2430 __ Bind(&type_arguments_uninstantiated);
2422 } 2431 }
2423 __ Bind(&type_arguments_uninstantiated);
2424 if (node->constructor().IsFactory()) { 2432 if (node->constructor().IsFactory()) {
2425 // A runtime call to instantiate the type arguments is required before 2433 // A runtime call to instantiate the type arguments is required before
2426 // calling the factory. 2434 // calling the factory.
2427 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2435 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2428 __ PushObject(node->type_arguments()); 2436 __ PushObject(node->type_arguments());
2429 __ pushl(EAX); // Push instantiator type arguments. 2437 __ pushl(EAX); // Push instantiator type arguments.
2430 GenerateCallRuntime(node->id(), 2438 GenerateCallRuntime(node->id(),
2431 node->token_index(), 2439 node->token_index(),
2432 kInstantiateTypeArgumentsRuntimeEntry); 2440 kInstantiateTypeArgumentsRuntimeEntry);
2433 __ popl(EAX); // Pop instantiator type arguments. 2441 __ popl(EAX); // Pop instantiator type arguments.
2434 __ popl(EAX); // Pop uninstantiated type arguments. 2442 __ popl(EAX); // Pop uninstantiated type arguments.
2435 __ popl(EAX); // Pop instantiated type arguments. 2443 __ popl(EAX); // Pop instantiated type arguments.
2436 __ Bind(&type_arguments_instantiated); 2444 __ Bind(&type_arguments_instantiated);
2437 __ pushl(EAX); // Instantiated type arguments. 2445 __ pushl(EAX); // Instantiated type arguments.
2438 } else { 2446 } else {
2439 // In the non-factory case, we rely on the allocation stub to 2447 // In the non-factory case, we rely on the allocation stub to
2440 // instantiate the type arguments. 2448 // instantiate the type arguments.
2441 __ PushObject(node->type_arguments()); 2449 __ PushObject(node->type_arguments());
2442 __ pushl(EAX); // Instantiator type arguments. 2450 __ pushl(EAX); // Instantiator type arguments.
2443 Label type_arguments_pushed; 2451 Label type_arguments_pushed;
2444 __ jmp(&type_arguments_pushed, Assembler::kNearJump); 2452 __ jmp(&type_arguments_pushed, Assembler::kNearJump);
2445 2453
2446 __ Bind(&type_arguments_instantiated); 2454 __ Bind(&type_arguments_instantiated);
2447 __ pushl(EAX); // Instantiated type arguments. 2455 __ pushl(EAX); // Instantiated type arguments.
2448 __ pushl(raw_null); // Null instantiator. 2456 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2449 __ Bind(&type_arguments_pushed); 2457 __ Bind(&type_arguments_pushed);
2450 } 2458 }
2451 } 2459 }
2452 } 2460 }
2453 2461
2454 2462
2455 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) { 2463 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) {
2456 if (node->constructor().IsFactory()) { 2464 if (node->constructor().IsFactory()) {
2457 const bool requires_type_arguments = true; // Always first arg to factory. 2465 const bool requires_type_arguments = true; // Always first arg to factory.
2458 GenerateTypeArguments(node, requires_type_arguments); 2466 GenerateTypeArguments(node, requires_type_arguments);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 } 2498 }
2491 2499
2492 if (IsResultNeeded(node)) { 2500 if (IsResultNeeded(node)) {
2493 __ pushl(EAX); // Set up return value from allocate. 2501 __ pushl(EAX); // Set up return value from allocate.
2494 } 2502 }
2495 2503
2496 // First argument(this) for constructor call which follows. 2504 // First argument(this) for constructor call which follows.
2497 __ pushl(EAX); 2505 __ pushl(EAX);
2498 // Second argument is the implicit construction phase parameter. 2506 // Second argument is the implicit construction phase parameter.
2499 // Run both the constructor initializer list and the constructor body. 2507 // Run both the constructor initializer list and the constructor body.
2500 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 2508 __ pushl(Immediate(Smi::RawValue(Function::kCtorPhaseAll)));
2501
2502 2509
2503 // Now setup rest of the arguments for the constructor call. 2510 // Now setup rest of the arguments for the constructor call.
2504 node->arguments()->Visit(this); 2511 node->arguments()->Visit(this);
2505 2512
2506 // Call the constructor. 2513 // Call the constructor.
2507 // +2 to include implicit receiver and phase arguments. 2514 // +2 to include implicit receiver and phase arguments.
2508 int num_args = node->arguments()->length() + 2; 2515 int num_args = node->arguments()->length() + 2;
2509 __ LoadObject(ECX, node->constructor()); 2516 __ LoadObject(ECX, node->constructor());
2510 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names())); 2517 __ LoadObject(EDX, ArgumentsDescriptor(num_args, node->arguments()->names()));
2511 GenerateCall(node->token_index(), 2518 GenerateCall(node->token_index(),
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2832 const Error& error = Error::Handle( 2839 const Error& error = Error::Handle(
2833 Parser::FormatError(script, token_index, "Error", format, args)); 2840 Parser::FormatError(script, token_index, "Error", format, args));
2834 va_end(args); 2841 va_end(args);
2835 Isolate::Current()->long_jump_base()->Jump(1, error); 2842 Isolate::Current()->long_jump_base()->Jump(1, error);
2836 UNREACHABLE(); 2843 UNREACHABLE();
2837 } 2844 }
2838 2845
2839 } // namespace dart 2846 } // namespace dart
2840 2847
2841 #endif // defined TARGET_ARCH_IA32 2848 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/code_generator_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698