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

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

Issue 8776020: Ongoing renaming of type classes: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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/object.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 955 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 // Evaluate the array elements. 966 // Evaluate the array elements.
967 for (int i = 0; i < node->length(); i++) { 967 for (int i = 0; i < node->length(); i++) {
968 AstNode* element = node->ElementAt(i); 968 AstNode* element = node->ElementAt(i);
969 element->Visit(this); 969 element->Visit(this);
970 } 970 }
971 971
972 // Allocate the array. 972 // Allocate the array.
973 // EDX : Array length as Smi. 973 // EDX : Array length as Smi.
974 // ECX : element type for the array. 974 // ECX : element type for the array.
975 __ movl(EDX, Immediate(Smi::RawValue(node->length()))); 975 __ movl(EDX, Immediate(Smi::RawValue(node->length())));
976 const TypeArguments& element_type = node->type_arguments(); 976 const AbstractTypeArguments& element_type = node->type_arguments();
977 ASSERT(element_type.IsNull() || element_type.IsInstantiated()); 977 ASSERT(element_type.IsNull() || element_type.IsInstantiated());
978 __ LoadObject(ECX, element_type); 978 __ LoadObject(ECX, element_type);
979 GenerateCall(node->token_index(), &StubCode::AllocateArrayLabel()); 979 GenerateCall(node->token_index(), &StubCode::AllocateArrayLabel());
980 980
981 // Pop the element values from the stack into the array. 981 // Pop the element values from the stack into the array.
982 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); 982 __ leal(ECX, FieldAddress(EAX, Array::data_offset()));
983 for (int i = node->length() - 1; i >= 0; i--) { 983 for (int i = node->length() - 1; i >= 0; i--) {
984 __ popl(Address(ECX, i * kWordSize)); 984 __ popl(Address(ECX, i * kWordSize));
985 } 985 }
986 986
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 __ jmp(&done, Assembler::kNearJump); 1400 __ jmp(&done, Assembler::kNearJump);
1401 1401
1402 __ Bind(&non_null); 1402 __ Bind(&non_null);
1403 1403
1404 const Class& type_class = Class::ZoneHandle(type.type_class()); 1404 const Class& type_class = Class::ZoneHandle(type.type_class());
1405 const bool requires_type_arguments = type_class.HasTypeArguments(); 1405 const bool requires_type_arguments = type_class.HasTypeArguments();
1406 // A Smi object cannot be the instance of a parameterized class. 1406 // A Smi object cannot be the instance of a parameterized class.
1407 // A class equality check is only applicable with a dst type of a 1407 // A class equality check is only applicable with a dst type of a
1408 // non-parameterized class or with a raw dst type of a parameterized class. 1408 // non-parameterized class or with a raw dst type of a parameterized class.
1409 if (requires_type_arguments) { 1409 if (requires_type_arguments) {
1410 const TypeArguments& type_arguments = 1410 const AbstractTypeArguments& type_arguments =
1411 TypeArguments::Handle(type.arguments()); 1411 AbstractTypeArguments::Handle(type.arguments());
1412 const bool is_raw_type = type_arguments.IsNull() || 1412 const bool is_raw_type = type_arguments.IsNull() ||
1413 type_arguments.IsDynamicTypes(type_arguments.Length()); 1413 type_arguments.IsDynamicTypes(type_arguments.Length());
1414 Label runtime_call; 1414 Label runtime_call;
1415 __ testl(EAX, Immediate(kSmiTagMask)); 1415 __ testl(EAX, Immediate(kSmiTagMask));
1416 __ j(ZERO, &runtime_call, Assembler::kNearJump); 1416 __ j(ZERO, &runtime_call, Assembler::kNearJump);
1417 // Object not Smi. 1417 // Object not Smi.
1418 if (is_raw_type) { 1418 if (is_raw_type) {
1419 if (type.IsListInterface()) { 1419 if (type.IsListInterface()) {
1420 Label push_result; 1420 Label push_result;
1421 // TODO(srdjan) also accept List<Object>. 1421 // TODO(srdjan) also accept List<Object>.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 1554
1555 // If dst_type is instantiated and non-parameterized, we can inline code 1555 // If dst_type is instantiated and non-parameterized, we can inline code
1556 // checking whether the assigned instance is a Smi. 1556 // checking whether the assigned instance is a Smi.
1557 if (dst_type.IsInstantiated()) { 1557 if (dst_type.IsInstantiated()) {
1558 const Class& dst_type_class = Class::ZoneHandle(dst_type.type_class()); 1558 const Class& dst_type_class = Class::ZoneHandle(dst_type.type_class());
1559 const bool dst_class_has_type_arguments = dst_type_class.HasTypeArguments(); 1559 const bool dst_class_has_type_arguments = dst_type_class.HasTypeArguments();
1560 // A Smi object cannot be the instance of a parameterized class. 1560 // A Smi object cannot be the instance of a parameterized class.
1561 // A class equality check is only applicable with a dst type of a 1561 // A class equality check is only applicable with a dst type of a
1562 // non-parameterized class or with a raw dst type of a parameterized class. 1562 // non-parameterized class or with a raw dst type of a parameterized class.
1563 if (dst_class_has_type_arguments) { 1563 if (dst_class_has_type_arguments) {
1564 const TypeArguments& dst_type_arguments = 1564 const AbstractTypeArguments& dst_type_arguments =
1565 TypeArguments::Handle(dst_type.arguments()); 1565 AbstractTypeArguments::Handle(dst_type.arguments());
1566 const bool is_raw_dst_type = dst_type_arguments.IsNull() || 1566 const bool is_raw_dst_type = dst_type_arguments.IsNull() ||
1567 dst_type_arguments.IsDynamicTypes(dst_type_arguments.Length()); 1567 dst_type_arguments.IsDynamicTypes(dst_type_arguments.Length());
1568 if (is_raw_dst_type) { 1568 if (is_raw_dst_type) {
1569 // Dynamic type argument, check only classes. 1569 // Dynamic type argument, check only classes.
1570 if (dst_type.IsListInterface()) { 1570 if (dst_type.IsListInterface()) {
1571 // TODO(srdjan) also accept List<Object>. 1571 // TODO(srdjan) also accept List<Object>.
1572 __ testl(EAX, Immediate(kSmiTagMask)); 1572 __ testl(EAX, Immediate(kSmiTagMask));
1573 __ j(ZERO, &runtime_call, Assembler::kNearJump); 1573 __ j(ZERO, &runtime_call, Assembler::kNearJump);
1574 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); 1574 __ movl(ECX, FieldAddress(EAX, Object::class_offset()));
1575 TestClassAndJump(*CoreClass("ObjectArray"), &done); 1575 TestClassAndJump(*CoreClass("ObjectArray"), &done);
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
2249 while (outer_function.IsLocalFunction()) { 2249 while (outer_function.IsLocalFunction()) {
2250 outer_function = outer_function.parent_function(); 2250 outer_function = outer_function.parent_function();
2251 } 2251 }
2252 if (outer_function.IsFactory()) { 2252 if (outer_function.IsFactory()) {
2253 instantiator_class = outer_function.signature_class(); 2253 instantiator_class = outer_function.signature_class();
2254 } else { 2254 } else {
2255 instantiator_class = outer_function.owner(); 2255 instantiator_class = outer_function.owner();
2256 } 2256 }
2257 if (instantiator_class.NumTypeParameters() == 0) { 2257 if (instantiator_class.NumTypeParameters() == 0) {
2258 // The type arguments are compile time constants. 2258 // The type arguments are compile time constants.
2259 TypeArguments& type_arguments = TypeArguments::ZoneHandle(); 2259 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
2260 // TODO(regis): Temporary type should be allocated in new gen heap. 2260 // TODO(regis): Temporary type should be allocated in new gen heap.
2261 Type& type = Type::Handle( 2261 Type& type = Type::Handle(
2262 Type::NewParameterizedType(instantiator_class, type_arguments)); 2262 Type::NewParameterizedType(instantiator_class, type_arguments));
2263 String& errmsg = String::Handle(); 2263 String& errmsg = String::Handle();
2264 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg); 2264 type = ClassFinalizer::FinalizeAndCanonicalizeType(type, &errmsg);
2265 if (!errmsg.IsNull()) { 2265 if (!errmsg.IsNull()) {
2266 ErrorMsg(token_index, errmsg.ToCString()); 2266 ErrorMsg(token_index, errmsg.ToCString());
2267 } 2267 }
2268 type_arguments = type.arguments(); 2268 type_arguments = type.arguments();
2269 __ PushObject(type_arguments); 2269 __ PushObject(type_arguments);
2270 } else { 2270 } else {
2271 ASSERT(parsed_function().instantiator() != NULL); 2271 ASSERT(parsed_function().instantiator() != NULL);
2272 parsed_function().instantiator()->Visit(this); 2272 parsed_function().instantiator()->Visit(this);
2273 if (!outer_function.IsFactory()) { 2273 if (!outer_function.IsFactory()) {
2274 __ popl(EAX); // Pop instantiator. 2274 __ popl(EAX); // Pop instantiator.
2275 // The instantiator is the receiver of the caller, which is not a factory. 2275 // The instantiator is the receiver of the caller, which is not a factory.
2276 // The receiver cannot be null; extract its TypeArguments object. 2276 // The receiver cannot be null; extract its AbstractTypeArguments object.
2277 // Note that in the factory case, the instantiator is the first parameter 2277 // Note that in the factory case, the instantiator is the first parameter
2278 // of the factory, i.e. already a TypeArguments object. 2278 // of the factory, i.e. already an AbstractTypeArguments object.
2279 intptr_t type_arguments_instance_field_offset = 2279 intptr_t type_arguments_instance_field_offset =
2280 instantiator_class.type_arguments_instance_field_offset(); 2280 instantiator_class.type_arguments_instance_field_offset();
2281 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); 2281 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
2282 __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset)); 2282 __ movl(EAX, FieldAddress(EAX, type_arguments_instance_field_offset));
2283 __ pushl(EAX); 2283 __ pushl(EAX);
2284 } 2284 }
2285 } 2285 }
2286 } 2286 }
2287 2287
2288 2288
(...skipping 22 matching lines...) Expand all
2311 if (!node->constructor().IsFactory()) { 2311 if (!node->constructor().IsFactory()) {
2312 // The allocator additionally requires the instantiator type arguments. 2312 // The allocator additionally requires the instantiator type arguments.
2313 __ pushl(raw_null); // Null instantiator. 2313 __ pushl(raw_null); // Null instantiator.
2314 } 2314 }
2315 } 2315 }
2316 } else { 2316 } else {
2317 // The type arguments are uninstantiated. 2317 // The type arguments are uninstantiated.
2318 ASSERT(requires_type_arguments); 2318 ASSERT(requires_type_arguments);
2319 GenerateInstantiatorTypeArguments(node->token_index()); 2319 GenerateInstantiatorTypeArguments(node->token_index());
2320 __ popl(EAX); // Pop instantiator. 2320 __ popl(EAX); // Pop instantiator.
2321 // EAX is the instantiator TypeArguments object (or null). 2321 // EAX is the instantiator AbstractTypeArguments object (or null).
2322 // If EAX is null, no need to instantiate the type arguments, use null, and 2322 // If EAX is null, no need to instantiate the type arguments, use null, and
2323 // allocate an object of a raw type. 2323 // allocate an object of a raw type.
2324 Label type_arguments_instantiated, type_arguments_uninstantiated; 2324 Label type_arguments_instantiated, type_arguments_uninstantiated;
2325 __ cmpl(EAX, raw_null); 2325 __ cmpl(EAX, raw_null);
2326 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2326 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2327 2327
2328 // Instantiate non-null type arguments. 2328 // Instantiate non-null type arguments.
2329 if (node->type_arguments().IsUninstantiatedIdentity()) { 2329 if (node->type_arguments().IsUninstantiatedIdentity()) {
2330 // Check if the instantiator type argument vector is a TypeArray of a 2330 // Check if the instantiator type argument vector is a TypeArguments of a
2331 // matching length and, if so, use it as the instantiated type_arguments. 2331 // matching length and, if so, use it as the instantiated type_arguments.
2332 __ LoadObject(ECX, Class::ZoneHandle(Object::type_array_class())); 2332 __ LoadObject(ECX, Class::ZoneHandle(Object::type_arguments_class()));
2333 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset())); 2333 __ cmpl(ECX, FieldAddress(EAX, Object::class_offset()));
2334 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 2334 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
2335 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>( 2335 Immediate arguments_length = Immediate(reinterpret_cast<int32_t>(
2336 Smi::New(node->type_arguments().Length()))); 2336 Smi::New(node->type_arguments().Length())));
2337 __ cmpl(FieldAddress(EAX, TypeArray::length_offset()), arguments_length); 2337 __ cmpl(FieldAddress(EAX, TypeArguments::length_offset()),
2338 arguments_length);
2338 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 2339 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
2339 } 2340 }
2340 __ Bind(&type_arguments_uninstantiated); 2341 __ Bind(&type_arguments_uninstantiated);
2341 if (node->constructor().IsFactory()) { 2342 if (node->constructor().IsFactory()) {
2342 // A runtime call to instantiate the type arguments is required before 2343 // A runtime call to instantiate the type arguments is required before
2343 // calling the factory. 2344 // calling the factory.
2344 const Object& result = Object::ZoneHandle(); 2345 const Object& result = Object::ZoneHandle();
2345 __ PushObject(result); // Make room for the result of the runtime call. 2346 __ PushObject(result); // Make room for the result of the runtime call.
2346 __ PushObject(node->type_arguments()); 2347 __ PushObject(node->type_arguments());
2347 __ pushl(EAX); // Push instantiator type arguments. 2348 __ pushl(EAX); // Push instantiator type arguments.
(...skipping 19 matching lines...) Expand all
2367 __ Bind(&type_arguments_pushed); 2368 __ Bind(&type_arguments_pushed);
2368 } 2369 }
2369 } 2370 }
2370 } 2371 }
2371 2372
2372 2373
2373 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) { 2374 void CodeGenerator::VisitConstructorCallNode(ConstructorCallNode* node) {
2374 if (node->constructor().IsFactory()) { 2375 if (node->constructor().IsFactory()) {
2375 const bool requires_type_arguments = true; // Always first arg to factory. 2376 const bool requires_type_arguments = true; // Always first arg to factory.
2376 GenerateTypeArguments(node, requires_type_arguments); 2377 GenerateTypeArguments(node, requires_type_arguments);
2377 // The top of stack is an instantiated TypeArguments object (or null). 2378 // The top of stack is an instantiated AbstractTypeArguments object
2379 // (or null).
2378 int num_args = node->arguments()->length() + 1; // +1 to include type args. 2380 int num_args = node->arguments()->length() + 1; // +1 to include type args.
2379 node->arguments()->Visit(this); 2381 node->arguments()->Visit(this);
2380 // Call the factory. 2382 // Call the factory.
2381 __ LoadObject(ECX, node->constructor()); 2383 __ LoadObject(ECX, node->constructor());
2382 __ LoadObject(EDX, ArgumentsDescriptor(num_args, 2384 __ LoadObject(EDX, ArgumentsDescriptor(num_args,
2383 node->arguments()->names())); 2385 node->arguments()->names()));
2384 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel()); 2386 GenerateCall(node->token_index(), &StubCode::CallStaticFunctionLabel());
2385 // Factory constructor returns object in EAX. 2387 // Factory constructor returns object in EAX.
2386 __ addl(ESP, Immediate(num_args * kWordSize)); 2388 __ addl(ESP, Immediate(num_args * kWordSize));
2387 if (IsResultNeeded(node)) { 2389 if (IsResultNeeded(node)) {
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2742 message_buffer, kMessageBufferSize, 2744 message_buffer, kMessageBufferSize,
2743 format, args); 2745 format, args);
2744 va_end(args); 2746 va_end(args);
2745 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); 2747 Isolate::Current()->long_jump_base()->Jump(1, message_buffer);
2746 UNREACHABLE(); 2748 UNREACHABLE();
2747 } 2749 }
2748 2750
2749 } // namespace dart 2751 } // namespace dart
2750 2752
2751 #endif // defined TARGET_ARCH_IA32 2753 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698