| OLD | NEW |
| 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 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 node->token_index(), | 1339 node->token_index(), |
| 1340 operator_name); | 1340 operator_name); |
| 1341 __ pushl(EAX); | 1341 __ pushl(EAX); |
| 1342 // TOS(0): value, TOS(1): index, TOS(2): array. | 1342 // TOS(0): value, TOS(1): index, TOS(2): array. |
| 1343 GenerateStoreIndexed(node->store_id(), | 1343 GenerateStoreIndexed(node->store_id(), |
| 1344 node->token_index(), | 1344 node->token_index(), |
| 1345 node->prefix() && IsResultNeeded(node)); | 1345 node->prefix() && IsResultNeeded(node)); |
| 1346 } | 1346 } |
| 1347 | 1347 |
| 1348 | 1348 |
| 1349 static const Class* CoreClass(const char* c_name) { |
| 1350 const String& class_name = String::Handle(String::NewSymbol(c_name)); |
| 1351 const Class& cls = Class::ZoneHandle(Library::Handle( |
| 1352 Library::CoreImplLibrary()).LookupClass(class_name)); |
| 1353 ASSERT(!cls.IsNull()); |
| 1354 return &cls; |
| 1355 } |
| 1356 |
| 1357 |
| 1349 // Optimize instanceof type test by adding inlined tests for: | 1358 // Optimize instanceof type test by adding inlined tests for: |
| 1350 // - NULL -> return false. | 1359 // - NULL -> return false. |
| 1351 // - Smi -> compile time subtype check (only if dst class is not parameterized). | 1360 // - Smi -> compile time subtype check (only if dst class is not parameterized). |
| 1352 // - Class equality (only if class is not parameterized). | 1361 // - Class equality (only if class is not parameterized). |
| 1353 // Inputs: | 1362 // Inputs: |
| 1354 // - EAX: object. | 1363 // - EAX: object. |
| 1355 // Destroys ECX. | 1364 // Destroys ECX. |
| 1356 // Returns: | 1365 // Returns: |
| 1357 // - true or false on stack. | 1366 // - true or false on stack. |
| 1358 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, | 1367 void CodeGenerator::GenerateInstanceOf(intptr_t node_id, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1400 if (requires_type_arguments) { | 1409 if (requires_type_arguments) { |
| 1401 const TypeArguments& type_arguments = | 1410 const TypeArguments& type_arguments = |
| 1402 TypeArguments::Handle(type.arguments()); | 1411 TypeArguments::Handle(type.arguments()); |
| 1403 const bool is_raw_type = type_arguments.IsNull() || | 1412 const bool is_raw_type = type_arguments.IsNull() || |
| 1404 type_arguments.IsDynamicTypes(type_arguments.Length()); | 1413 type_arguments.IsDynamicTypes(type_arguments.Length()); |
| 1405 Label runtime_call; | 1414 Label runtime_call; |
| 1406 __ testl(EAX, Immediate(kSmiTagMask)); | 1415 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1407 __ j(ZERO, &runtime_call, Assembler::kNearJump); | 1416 __ j(ZERO, &runtime_call, Assembler::kNearJump); |
| 1408 // Object not Smi. | 1417 // Object not Smi. |
| 1409 if (is_raw_type) { | 1418 if (is_raw_type) { |
| 1410 if (!type_class.is_interface()) { | 1419 if (type.IsListInterface()) { |
| 1420 Label push_result; |
| 1421 // TODO(srdjan) also accept List<Object>. |
| 1422 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| 1423 __ CompareObject(ECX, *CoreClass("ObjectArray")); |
| 1424 __ j(EQUAL, &push_result, Assembler::kNearJump); |
| 1425 __ CompareObject(ECX, *CoreClass("GrowableObjectArray")); |
| 1426 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); |
| 1427 __ Bind(&push_result); |
| 1428 __ PushObject(negate_result ? bool_false : bool_true); |
| 1429 __ jmp(&done, Assembler::kNearJump); |
| 1430 } else if (!type_class.is_interface()) { |
| 1411 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); | 1431 __ movl(ECX, FieldAddress(EAX, Object::class_offset())); |
| 1412 __ CompareObject(ECX, type_class); | 1432 __ CompareObject(ECX, type_class); |
| 1413 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); | 1433 __ j(NOT_EQUAL, &runtime_call, Assembler::kNearJump); |
| 1414 __ PushObject(negate_result ? bool_false : bool_true); | 1434 __ PushObject(negate_result ? bool_false : bool_true); |
| 1415 __ jmp(&done, Assembler::kNearJump); | 1435 __ jmp(&done, Assembler::kNearJump); |
| 1416 } | 1436 } |
| 1417 } | 1437 } |
| 1418 __ Bind(&runtime_call); | 1438 __ Bind(&runtime_call); |
| 1419 // Fall through to runtime call. | 1439 // Fall through to runtime call. |
| 1420 } else { | 1440 } else { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1485 | 1505 |
| 1486 // Jumps to label if ECX equals the given class. | 1506 // Jumps to label if ECX equals the given class. |
| 1487 // Inputs: | 1507 // Inputs: |
| 1488 // - ECX: tested class. | 1508 // - ECX: tested class. |
| 1489 void CodeGenerator::TestClassAndJump(const Class& cls, Label* label) { | 1509 void CodeGenerator::TestClassAndJump(const Class& cls, Label* label) { |
| 1490 __ CompareObject(ECX, cls); | 1510 __ CompareObject(ECX, cls); |
| 1491 __ j(EQUAL, label, Assembler::kNearJump); | 1511 __ j(EQUAL, label, Assembler::kNearJump); |
| 1492 } | 1512 } |
| 1493 | 1513 |
| 1494 | 1514 |
| 1495 static const Class* CoreClass(const char* c_name) { | |
| 1496 const String& class_name = String::Handle(String::NewSymbol(c_name)); | |
| 1497 const Class& cls = Class::ZoneHandle(Library::Handle( | |
| 1498 Library::CoreImplLibrary()).LookupClass(class_name)); | |
| 1499 ASSERT(!cls.IsNull()); | |
| 1500 return &cls; | |
| 1501 } | |
| 1502 | |
| 1503 | |
| 1504 // Optimize assignable type check by adding inlined tests for: | 1515 // Optimize assignable type check by adding inlined tests for: |
| 1505 // - NULL -> return NULL. | 1516 // - NULL -> return NULL. |
| 1506 // - Smi -> compile time subtype check (only if dst class is not parameterized). | 1517 // - Smi -> compile time subtype check (only if dst class is not parameterized). |
| 1507 // - Class equality (only if class is not parameterized). | 1518 // - Class equality (only if class is not parameterized). |
| 1508 // Inputs: | 1519 // Inputs: |
| 1509 // - EAX: object. | 1520 // - EAX: object. |
| 1510 // Destroys ECX and EDX. | 1521 // Destroys ECX and EDX. |
| 1511 // Returns: | 1522 // Returns: |
| 1512 // - object in EAX for successful assignable check (or throws TypeError). | 1523 // - object in EAX for successful assignable check (or throws TypeError). |
| 1513 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, | 1524 void CodeGenerator::GenerateAssertAssignable(intptr_t node_id, |
| (...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2731 message_buffer, kMessageBufferSize, | 2742 message_buffer, kMessageBufferSize, |
| 2732 format, args); | 2743 format, args); |
| 2733 va_end(args); | 2744 va_end(args); |
| 2734 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); | 2745 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 2735 UNREACHABLE(); | 2746 UNREACHABLE(); |
| 2736 } | 2747 } |
| 2737 | 2748 |
| 2738 } // namespace dart | 2749 } // namespace dart |
| 2739 | 2750 |
| 2740 #endif // defined TARGET_ARCH_IA32 | 2751 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |