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

Side by Side Diff: runtime/vm/code_generator_x64.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_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/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 } else { 704 } else {
705 __ LoadObject(RAX, literal); 705 __ LoadObject(RAX, literal);
706 } 706 }
707 } else { 707 } else {
708 // Pop the previously evaluated result value into RAX. 708 // Pop the previously evaluated result value into RAX.
709 __ popq(RAX); 709 __ popq(RAX);
710 } 710 }
711 711
712 // Generate type check. 712 // Generate type check.
713 if (FLAG_enable_type_checks) { 713 if (FLAG_enable_type_checks) {
714 const RawFunction::Kind kind = parsed_function().function().kind(); 714 const bool returns_null = node->value()->IsLiteralNode() &&
715 node->value()->AsLiteralNode()->literal().IsNull();
716 const RawFunction::Kind kind = parsed_function().function().kind();
715 // Implicit getters do not need a type check at return. 717 // Implicit getters do not need a type check at return.
716 if ((kind != RawFunction::kImplicitGetter) && 718 if (!returns_null &&
719 (kind != RawFunction::kImplicitGetter) &&
717 (kind != RawFunction::kConstImplicitGetter)) { 720 (kind != RawFunction::kConstImplicitGetter)) {
718 GenerateAssertAssignable( 721 GenerateAssertAssignable(
719 node->id(), 722 node->id(),
720 node->value()->token_index(), 723 node->value()->token_index(),
721 AbstractType::ZoneHandle(parsed_function().function().result_type()), 724 AbstractType::ZoneHandle(parsed_function().function().result_type()),
722 String::ZoneHandle(String::NewSymbol("function result"))); 725 String::ZoneHandle(String::NewSymbol("function result")));
723 } 726 }
724 } 727 }
725 GenerateReturnEpilog(node); 728 GenerateReturnEpilog(node);
726 } 729 }
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 1322
1320 const Class& type_class = Class::ZoneHandle(type.type_class()); 1323 const Class& type_class = Class::ZoneHandle(type.type_class());
1321 const bool requires_type_arguments = type_class.HasTypeArguments(); 1324 const bool requires_type_arguments = type_class.HasTypeArguments();
1322 // A Smi object cannot be the instance of a parameterized class. 1325 // A Smi object cannot be the instance of a parameterized class.
1323 // A class equality check is only applicable with a dst type of a 1326 // A class equality check is only applicable with a dst type of a
1324 // non-parameterized class or with a raw dst type of a parameterized class. 1327 // non-parameterized class or with a raw dst type of a parameterized class.
1325 if (requires_type_arguments) { 1328 if (requires_type_arguments) {
1326 const AbstractTypeArguments& type_arguments = 1329 const AbstractTypeArguments& type_arguments =
1327 AbstractTypeArguments::Handle(type.arguments()); 1330 AbstractTypeArguments::Handle(type.arguments());
1328 const bool is_raw_type = type_arguments.IsNull() || 1331 const bool is_raw_type = type_arguments.IsNull() ||
1329 type_arguments.IsDynamicTypes(type_arguments.Length()); 1332 type_arguments.IsRaw(type_arguments.Length());
1330 Label runtime_call; 1333 Label runtime_call;
1331 __ testq(RAX, Immediate(kSmiTagMask)); 1334 __ testq(RAX, Immediate(kSmiTagMask));
1332 __ j(ZERO, &runtime_call, Assembler::kNearJump); 1335 __ j(ZERO, &runtime_call, Assembler::kNearJump);
1333 // Object not Smi. 1336 // Object not Smi.
1334 if (is_raw_type) { 1337 if (is_raw_type) {
1335 if (type.IsListInterface()) { 1338 if (type.IsListInterface()) {
1336 Label push_result; 1339 Label push_result;
1337 // TODO(srdjan) also accept List<Object>. 1340 // TODO(srdjan) also accept List<Object>.
1338 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1341 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1339 __ CompareObject(RCX, *CoreClass("ObjectArray")); 1342 __ CompareObject(RCX, *CoreClass("ObjectArray"));
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1498 if (dst_type.IsInstantiated()) { 1501 if (dst_type.IsInstantiated()) {
1499 const Class& dst_type_class = Class::ZoneHandle(dst_type.type_class()); 1502 const Class& dst_type_class = Class::ZoneHandle(dst_type.type_class());
1500 const bool dst_class_has_type_arguments = dst_type_class.HasTypeArguments(); 1503 const bool dst_class_has_type_arguments = dst_type_class.HasTypeArguments();
1501 // A Smi object cannot be the instance of a parameterized class. 1504 // A Smi object cannot be the instance of a parameterized class.
1502 // A class equality check is only applicable with a dst type of a 1505 // A class equality check is only applicable with a dst type of a
1503 // non-parameterized class or with a raw dst type of a parameterized class. 1506 // non-parameterized class or with a raw dst type of a parameterized class.
1504 if (dst_class_has_type_arguments) { 1507 if (dst_class_has_type_arguments) {
1505 const AbstractTypeArguments& dst_type_arguments = 1508 const AbstractTypeArguments& dst_type_arguments =
1506 AbstractTypeArguments::Handle(dst_type.arguments()); 1509 AbstractTypeArguments::Handle(dst_type.arguments());
1507 const bool is_raw_dst_type = dst_type_arguments.IsNull() || 1510 const bool is_raw_dst_type = dst_type_arguments.IsNull() ||
1508 dst_type_arguments.IsDynamicTypes(dst_type_arguments.Length()); 1511 dst_type_arguments.IsRaw(dst_type_arguments.Length());
1509 if (is_raw_dst_type) { 1512 if (is_raw_dst_type) {
1510 // Dynamic type argument, check only classes. 1513 // Dynamic type argument, check only classes.
1511 if (dst_type.IsListInterface()) { 1514 if (dst_type.IsListInterface()) {
1512 // TODO(srdjan) also accept List<Object>. 1515 // TODO(srdjan) also accept List<Object>.
1513 __ testq(RAX, Immediate(kSmiTagMask)); 1516 __ testq(RAX, Immediate(kSmiTagMask));
1514 __ j(ZERO, &runtime_call); 1517 __ j(ZERO, &runtime_call);
1515 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 1518 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
1516 TestClassAndJump(*CoreClass("ObjectArray"), &done); 1519 TestClassAndJump(*CoreClass("ObjectArray"), &done);
1517 TestClassAndJump(*CoreClass("GrowableObjectArray"), &done); 1520 TestClassAndJump(*CoreClass("GrowableObjectArray"), &done);
1518 } else if (!dst_type_class.is_interface()) { 1521 } else if (!dst_type_class.is_interface()) {
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
2257 bool requires_type_arguments) { 2260 bool requires_type_arguments) {
2258 const Immediate raw_null = 2261 const Immediate raw_null =
2259 Immediate(reinterpret_cast<intptr_t>(Object::null())); 2262 Immediate(reinterpret_cast<intptr_t>(Object::null()));
2260 // Instantiate the type arguments if necessary. 2263 // Instantiate the type arguments if necessary.
2261 if (node->type_arguments().IsNull() || 2264 if (node->type_arguments().IsNull() ||
2262 node->type_arguments().IsInstantiated()) { 2265 node->type_arguments().IsInstantiated()) {
2263 if (requires_type_arguments) { 2266 if (requires_type_arguments) {
2264 // A factory requires the type arguments as first parameter. 2267 // A factory requires the type arguments as first parameter.
2265 __ PushObject(node->type_arguments()); 2268 __ PushObject(node->type_arguments());
2266 if (!node->constructor().IsFactory()) { 2269 if (!node->constructor().IsFactory()) {
2267 // The allocator additionally requires the instantiator type arguments. 2270 // The non-factory allocator additionally requires the instantiator
2268 __ pushq(raw_null); // Null instantiator. 2271 // type arguments which are not needed here, since the type arguments
2272 // are instantiated.
2273 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2269 } 2274 }
2270 } 2275 }
2271 } else { 2276 } else {
2272 // The type arguments are uninstantiated. 2277 // The type arguments are uninstantiated.
2273 ASSERT(requires_type_arguments); 2278 ASSERT(requires_type_arguments);
2274 GenerateInstantiatorTypeArguments(node->token_index()); 2279 GenerateInstantiatorTypeArguments(node->token_index());
2275 __ popq(RAX); // Pop instantiator. 2280 __ popq(RAX); // Pop instantiator.
2276 // RAX is the instantiator AbstractTypeArguments object (or null). 2281 // RAX is the instantiator AbstractTypeArguments object (or null).
2277 // If RAX is null, no need to instantiate the type arguments, use null, and 2282 // If the instantiator is null and if the type argument vector
2278 // allocate an object of a raw type. 2283 // instantiated from null becomes a vector of Dynamic, then use null as
2279 Label type_arguments_instantiated, type_arguments_uninstantiated; 2284 // the type arguments.
2280 __ cmpq(RAX, raw_null); 2285 Label type_arguments_instantiated;
2281 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2286 const intptr_t len = node->type_arguments().Length();
2282 2287 if (node->type_arguments().IsRawInstantiatedRaw(len)) {
2288 __ cmpq(RAX, raw_null);
2289 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2290 }
2283 // Instantiate non-null type arguments. 2291 // Instantiate non-null type arguments.
2284 if (node->type_arguments().IsUninstantiatedIdentity()) { 2292 if (node->type_arguments().IsUninstantiatedIdentity()) {
2285 // Check if the instantiator type argument vector is a TypeArguments of a 2293 // Check if the instantiator type argument vector is a TypeArguments of a
2286 // matching length and, if so, use it as the instantiated type_arguments. 2294 // matching length and, if so, use it as the instantiated type_arguments.
2295 // No need to check RAX for null (again), because a null instance will
2296 // have the wrong class (Null instead of TypeArguments).
2297 Label type_arguments_uninstantiated;
2287 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 2298 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
2288 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 2299 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
2289 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 2300 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
2290 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>( 2301 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>(
2291 Smi::New(node->type_arguments().Length()))); 2302 Smi::New(node->type_arguments().Length())));
2292 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 2303 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
2293 arguments_length); 2304 arguments_length);
2294 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2305 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2306 __ Bind(&type_arguments_uninstantiated);
2295 } 2307 }
2296 __ Bind(&type_arguments_uninstantiated);
2297 if (node->constructor().IsFactory()) { 2308 if (node->constructor().IsFactory()) {
2298 // A runtime call to instantiate the type arguments is required before 2309 // A runtime call to instantiate the type arguments is required before
2299 // calling the factory. 2310 // calling the factory.
2300 __ PushObject(Object::ZoneHandle()); // Make room for the result. 2311 __ PushObject(Object::ZoneHandle()); // Make room for the result.
2301 __ PushObject(node->type_arguments()); 2312 __ PushObject(node->type_arguments());
2302 __ pushq(RAX); // Push instantiator type arguments. 2313 __ pushq(RAX); // Push instantiator type arguments.
2303 GenerateCallRuntime(node->id(), 2314 GenerateCallRuntime(node->id(),
2304 node->token_index(), 2315 node->token_index(),
2305 kInstantiateTypeArgumentsRuntimeEntry); 2316 kInstantiateTypeArgumentsRuntimeEntry);
2306 __ popq(RAX); // Pop instantiator type arguments. 2317 __ popq(RAX); // Pop instantiator type arguments.
2307 __ popq(RAX); // Pop uninstantiated type arguments. 2318 __ popq(RAX); // Pop uninstantiated type arguments.
2308 __ popq(RAX); // Pop instantiated type arguments. 2319 __ popq(RAX); // Pop instantiated type arguments.
2309 __ Bind(&type_arguments_instantiated); 2320 __ Bind(&type_arguments_instantiated);
2310 __ pushq(RAX); // Instantiated type arguments. 2321 __ pushq(RAX); // Instantiated type arguments.
2311 } else { 2322 } else {
2312 // In the non-factory case, we rely on the allocation stub to 2323 // In the non-factory case, we rely on the allocation stub to
2313 // instantiate the type arguments. 2324 // instantiate the type arguments.
2314 __ PushObject(node->type_arguments()); 2325 __ PushObject(node->type_arguments());
2315 __ pushq(RAX); // Instantiator type arguments. 2326 __ pushq(RAX); // Instantiator type arguments.
2316 Label type_arguments_pushed; 2327 Label type_arguments_pushed;
2317 __ jmp(&type_arguments_pushed, Assembler::kNearJump); 2328 __ jmp(&type_arguments_pushed, Assembler::kNearJump);
2318 2329
2319 __ Bind(&type_arguments_instantiated); 2330 __ Bind(&type_arguments_instantiated);
2320 __ pushq(RAX); // Instantiated type arguments. 2331 __ pushq(RAX); // Instantiated type arguments.
2321 __ pushq(raw_null); // Null instantiator. 2332 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
2322 __ Bind(&type_arguments_pushed); 2333 __ Bind(&type_arguments_pushed);
2323 } 2334 }
2324 } 2335 }
2325 } 2336 }
2326 2337
2327 2338
2328 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) { 2339 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) {
2329 if (node->constructor().IsFactory()) { 2340 if (node->constructor().IsFactory()) {
2330 const bool requires_type_arguments = true; // Always first arg to factory. 2341 const bool requires_type_arguments = true; // Always first arg to factory.
2331 GenerateTypeArguments(node, requires_type_arguments); 2342 GenerateTypeArguments(node, requires_type_arguments);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2363 } 2374 }
2364 2375
2365 if (IsResultNeeded(node)) { 2376 if (IsResultNeeded(node)) {
2366 __ pushq(RAX); // Set up return value from allocate. 2377 __ pushq(RAX); // Set up return value from allocate.
2367 } 2378 }
2368 2379
2369 // First argument(this) for constructor call which follows. 2380 // First argument(this) for constructor call which follows.
2370 __ pushq(RAX); 2381 __ pushq(RAX);
2371 // Second argument is the implicit construction phase parameter. 2382 // Second argument is the implicit construction phase parameter.
2372 // Run both the constructor initializer list and the constructor body. 2383 // Run both the constructor initializer list and the constructor body.
2373 __ PushObject(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); 2384 __ pushq(Immediate(Smi::RawValue(Function::kCtorPhaseAll)));
2374
2375 2385
2376 // Now setup rest of the arguments for the constructor call. 2386 // Now setup rest of the arguments for the constructor call.
2377 node->arguments()->Visit(this); 2387 node->arguments()->Visit(this);
2378 2388
2379 // Call the constructor. 2389 // Call the constructor.
2380 // +2 to include implicit receiver and phase arguments. 2390 // +2 to include implicit receiver and phase arguments.
2381 int num_args = node->arguments()->length() + 2; 2391 int num_args = node->arguments()->length() + 2;
2382 __ LoadObject(RBX, node->constructor()); 2392 __ LoadObject(RBX, node->constructor());
2383 __ LoadObject(R10, ArgumentsDescriptor(num_args, node->arguments()->names())); 2393 __ LoadObject(R10, ArgumentsDescriptor(num_args, node->arguments()->names()));
2384 GenerateCall(node->token_index(), 2394 GenerateCall(node->token_index(),
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 const Error& error = Error::Handle( 2715 const Error& error = Error::Handle(
2706 Parser::FormatError(script, token_index, "Error", format, args)); 2716 Parser::FormatError(script, token_index, "Error", format, args));
2707 va_end(args); 2717 va_end(args);
2708 Isolate::Current()->long_jump_base()->Jump(1, error); 2718 Isolate::Current()->long_jump_base()->Jump(1, error);
2709 UNREACHABLE(); 2719 UNREACHABLE();
2710 } 2720 }
2711 2721
2712 } // namespace dart 2722 } // namespace dart
2713 2723
2714 #endif // defined TARGET_ARCH_X64 2724 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698