| 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 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 __ pushl(Address(EBP, variable.index() * kWordSize)); | 419 __ pushl(Address(EBP, variable.index() * kWordSize)); |
| 420 } | 420 } |
| 421 } | 421 } |
| 422 | 422 |
| 423 | 423 |
| 424 void CodeGenerator::GenerateInstanceCall( | 424 void CodeGenerator::GenerateInstanceCall( |
| 425 intptr_t node_id, | 425 intptr_t node_id, |
| 426 intptr_t token_index, | 426 intptr_t token_index, |
| 427 const String& function_name, | 427 const String& function_name, |
| 428 int num_arguments, | 428 int num_arguments, |
| 429 const Array& optional_arguments_names) { | 429 const Array& optional_arguments_names, |
| 430 intptr_t num_args_checked) { |
| 431 ASSERT(num_args_checked > 0); // At least receiver check is necessary. |
| 430 // Set up the function name and number of arguments (including the receiver) | 432 // Set up the function name and number of arguments (including the receiver) |
| 431 // to the InstanceCall stub which will resolve the correct entrypoint for | 433 // to the InstanceCall stub which will resolve the correct entrypoint for |
| 432 // the operator and call it. | 434 // the operator and call it. |
| 433 ICData ic_data(function_name, 1); | 435 ICData ic_data(function_name, num_args_checked); |
| 434 __ LoadObject(ECX, Array::ZoneHandle(ic_data.data())); | 436 __ LoadObject(ECX, Array::ZoneHandle(ic_data.data())); |
| 435 __ LoadObject(EDX, ArgumentsDescriptor(num_arguments, | 437 __ LoadObject(EDX, ArgumentsDescriptor(num_arguments, |
| 436 optional_arguments_names)); | 438 optional_arguments_names)); |
| 437 ExternalLabel target_label( | 439 uword label_address = 0; |
| 438 "InlineCache", StubCode::InlineCacheEntryPoint()); | 440 switch (num_args_checked) { |
| 441 case 1: |
| 442 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); |
| 443 break; |
| 444 case 2: |
| 445 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); |
| 446 break; |
| 447 default: |
| 448 UNIMPLEMENTED(); |
| 449 } |
| 450 ExternalLabel target_label("InlineCache", label_address); |
| 439 | 451 |
| 440 __ call(&target_label); | 452 __ call(&target_label); |
| 441 AddCurrentDescriptor(PcDescriptors::kIcCall, | 453 AddCurrentDescriptor(PcDescriptors::kIcCall, |
| 442 node_id, | 454 node_id, |
| 443 token_index); | 455 token_index); |
| 444 __ addl(ESP, Immediate(num_arguments * kWordSize)); | 456 __ addl(ESP, Immediate(num_arguments * kWordSize)); |
| 445 } | 457 } |
| 446 | 458 |
| 447 | 459 |
| 448 // Call to generate entry code: | 460 // Call to generate entry code: |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 | 1055 |
| 1044 | 1056 |
| 1045 // Expects array and index on stack and returns result in EAX. | 1057 // Expects array and index on stack and returns result in EAX. |
| 1046 void CodeGenerator::GenerateLoadIndexed(intptr_t node_id, | 1058 void CodeGenerator::GenerateLoadIndexed(intptr_t node_id, |
| 1047 intptr_t token_index) { | 1059 intptr_t token_index) { |
| 1048 // Invoke the [] operator on the receiver object with the index as argument. | 1060 // Invoke the [] operator on the receiver object with the index as argument. |
| 1049 const String& operator_name = | 1061 const String& operator_name = |
| 1050 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); | 1062 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); |
| 1051 const int kNumArguments = 2; // Receiver and index. | 1063 const int kNumArguments = 2; // Receiver and index. |
| 1052 const Array& kNoArgumentNames = Array::Handle(); | 1064 const Array& kNoArgumentNames = Array::Handle(); |
| 1065 const int kNumArgumentsChecked = 1; |
| 1053 GenerateInstanceCall(node_id, | 1066 GenerateInstanceCall(node_id, |
| 1054 token_index, | 1067 token_index, |
| 1055 operator_name, | 1068 operator_name, |
| 1056 kNumArguments, | 1069 kNumArguments, |
| 1057 kNoArgumentNames); | 1070 kNoArgumentNames, |
| 1071 kNumArgumentsChecked); |
| 1058 } | 1072 } |
| 1059 | 1073 |
| 1060 | 1074 |
| 1061 void CodeGenerator::VisitLoadIndexedNode(LoadIndexedNode* node) { | 1075 void CodeGenerator::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 1062 node->array()->Visit(this); | 1076 node->array()->Visit(this); |
| 1063 // Now compute the index. | 1077 // Now compute the index. |
| 1064 node->index_expr()->Visit(this); | 1078 node->index_expr()->Visit(this); |
| 1065 MarkDeoptPoint(node->id(), node->token_index()); | 1079 MarkDeoptPoint(node->id(), node->token_index()); |
| 1066 GenerateLoadIndexed(node->id(), node->token_index()); | 1080 GenerateLoadIndexed(node->id(), node->token_index()); |
| 1067 // Result is in EAX. | 1081 // Result is in EAX. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1088 __ pushl(ECX); // Restore arguments. | 1102 __ pushl(ECX); // Restore arguments. |
| 1089 __ pushl(EDX); | 1103 __ pushl(EDX); |
| 1090 __ pushl(EAX); | 1104 __ pushl(EAX); |
| 1091 } | 1105 } |
| 1092 // Invoke the []= operator on the receiver object with index and | 1106 // Invoke the []= operator on the receiver object with index and |
| 1093 // value as arguments. | 1107 // value as arguments. |
| 1094 const String& operator_name = | 1108 const String& operator_name = |
| 1095 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 1109 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 1096 const int kNumArguments = 3; // Receiver, index and value. | 1110 const int kNumArguments = 3; // Receiver, index and value. |
| 1097 const Array& kNoArgumentNames = Array::Handle(); | 1111 const Array& kNoArgumentNames = Array::Handle(); |
| 1112 const int kNumArgumentsChecked = 1; |
| 1098 GenerateInstanceCall(node_id, | 1113 GenerateInstanceCall(node_id, |
| 1099 token_index, | 1114 token_index, |
| 1100 operator_name, | 1115 operator_name, |
| 1101 kNumArguments, | 1116 kNumArguments, |
| 1102 kNoArgumentNames); | 1117 kNoArgumentNames, |
| 1118 kNumArgumentsChecked); |
| 1103 } | 1119 } |
| 1104 | 1120 |
| 1105 | 1121 |
| 1106 void CodeGenerator::VisitStoreIndexedNode(StoreIndexedNode* node) { | 1122 void CodeGenerator::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 1107 // Compute the receiver object and pass as first argument to call. | 1123 // Compute the receiver object and pass as first argument to call. |
| 1108 node->array()->Visit(this); | 1124 node->array()->Visit(this); |
| 1109 // Now compute the index. | 1125 // Now compute the index. |
| 1110 node->index_expr()->Visit(this); | 1126 node->index_expr()->Visit(this); |
| 1111 // Finally compute the value to assign. | 1127 // Finally compute the value to assign. |
| 1112 node->value()->Visit(this); | 1128 node->value()->Visit(this); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 } | 1196 } |
| 1181 MarkDeoptPoint(node->id(), node->token_index()); | 1197 MarkDeoptPoint(node->id(), node->token_index()); |
| 1182 String& operator_name = String::ZoneHandle(); | 1198 String& operator_name = String::ZoneHandle(); |
| 1183 if (node->kind() == Token::kSUB) { | 1199 if (node->kind() == Token::kSUB) { |
| 1184 operator_name = String::NewSymbol(Token::Str(Token::kNEGATE)); | 1200 operator_name = String::NewSymbol(Token::Str(Token::kNEGATE)); |
| 1185 } else { | 1201 } else { |
| 1186 operator_name = String::NewSymbol(node->Name()); | 1202 operator_name = String::NewSymbol(node->Name()); |
| 1187 } | 1203 } |
| 1188 const int kNumberOfArguments = 1; | 1204 const int kNumberOfArguments = 1; |
| 1189 const Array& kNoArgumentNames = Array::Handle(); | 1205 const Array& kNoArgumentNames = Array::Handle(); |
| 1206 const int kNumArgumentsChecked = 1; |
| 1190 GenerateInstanceCall(node->id(), | 1207 GenerateInstanceCall(node->id(), |
| 1191 node->token_index(), | 1208 node->token_index(), |
| 1192 operator_name, | 1209 operator_name, |
| 1193 kNumberOfArguments, | 1210 kNumberOfArguments, |
| 1194 kNoArgumentNames); | 1211 kNoArgumentNames, |
| 1212 kNumArgumentsChecked); |
| 1195 if (IsResultNeeded(node)) { | 1213 if (IsResultNeeded(node)) { |
| 1196 __ pushl(EAX); | 1214 __ pushl(EAX); |
| 1197 } | 1215 } |
| 1198 } | 1216 } |
| 1199 | 1217 |
| 1200 | 1218 |
| 1201 void CodeGenerator::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 1219 void CodeGenerator::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 1202 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 1220 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 1203 MarkDeoptPoint(node->id(), node->token_index()); | 1221 MarkDeoptPoint(node->id(), node->token_index()); |
| 1204 GenerateLoadVariable(EAX, node->local()); | 1222 GenerateLoadVariable(EAX, node->local()); |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 __ jmp(&null_done, Assembler::kNearJump); | 1825 __ jmp(&null_done, Assembler::kNearJump); |
| 1808 __ Bind(&load_true); | 1826 __ Bind(&load_true); |
| 1809 __ LoadObject(EAX, bool_true); | 1827 __ LoadObject(EAX, bool_true); |
| 1810 __ jmp(&null_done, Assembler::kNearJump); | 1828 __ jmp(&null_done, Assembler::kNearJump); |
| 1811 __ Bind(&non_null_compare); | 1829 __ Bind(&non_null_compare); |
| 1812 } | 1830 } |
| 1813 // Do '==' first then negate if necessary, | 1831 // Do '==' first then negate if necessary, |
| 1814 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); | 1832 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); |
| 1815 const int kNumberOfArguments = 2; | 1833 const int kNumberOfArguments = 2; |
| 1816 const Array& kNoArgumentNames = Array::Handle(); | 1834 const Array& kNoArgumentNames = Array::Handle(); |
| 1835 const int kNumArgumentsChecked = 1; |
| 1817 GenerateInstanceCall(node->id(), | 1836 GenerateInstanceCall(node->id(), |
| 1818 node->token_index(), | 1837 node->token_index(), |
| 1819 operator_name, | 1838 operator_name, |
| 1820 kNumberOfArguments, | 1839 kNumberOfArguments, |
| 1821 kNoArgumentNames); | 1840 kNoArgumentNames, |
| 1841 kNumArgumentsChecked); |
| 1822 | 1842 |
| 1823 // Result is in EAX. No need to negate if result is not needed. | 1843 // Result is in EAX. No need to negate if result is not needed. |
| 1824 if ((node->kind() == Token::kNE) && IsResultNeeded(node)) { | 1844 if ((node->kind() == Token::kNE) && IsResultNeeded(node)) { |
| 1825 // Negate result. | 1845 // Negate result. |
| 1826 Label load_true, done; | 1846 Label load_true, done; |
| 1827 __ LoadObject(EDX, bool_false); | 1847 __ LoadObject(EDX, bool_false); |
| 1828 __ cmpl(EAX, EDX); | 1848 __ cmpl(EAX, EDX); |
| 1829 __ j(EQUAL, &load_true, Assembler::kNearJump); | 1849 __ j(EQUAL, &load_true, Assembler::kNearJump); |
| 1830 __ movl(EAX, EDX); // false. | 1850 __ movl(EAX, EDX); // false. |
| 1831 __ jmp(&done, Assembler::kNearJump); | 1851 __ jmp(&done, Assembler::kNearJump); |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 | 2094 |
| 2075 | 2095 |
| 2076 // Expect receiver(left operand) and right operand on stack. | 2096 // Expect receiver(left operand) and right operand on stack. |
| 2077 // Return result in EAX. | 2097 // Return result in EAX. |
| 2078 void CodeGenerator::GenerateBinaryOperatorCall(intptr_t node_id, | 2098 void CodeGenerator::GenerateBinaryOperatorCall(intptr_t node_id, |
| 2079 intptr_t token_index, | 2099 intptr_t token_index, |
| 2080 const char* name) { | 2100 const char* name) { |
| 2081 const String& operator_name = String::ZoneHandle(String::NewSymbol(name)); | 2101 const String& operator_name = String::ZoneHandle(String::NewSymbol(name)); |
| 2082 const int kNumberOfArguments = 2; | 2102 const int kNumberOfArguments = 2; |
| 2083 const Array& kNoArgumentNames = Array::Handle(); | 2103 const Array& kNoArgumentNames = Array::Handle(); |
| 2104 const int kNumArgumentsChecked = 2; |
| 2084 GenerateInstanceCall(node_id, | 2105 GenerateInstanceCall(node_id, |
| 2085 token_index, | 2106 token_index, |
| 2086 operator_name, | 2107 operator_name, |
| 2087 kNumberOfArguments, | 2108 kNumberOfArguments, |
| 2088 kNoArgumentNames); | 2109 kNoArgumentNames, |
| 2110 kNumArgumentsChecked); |
| 2089 } | 2111 } |
| 2090 | 2112 |
| 2091 | 2113 |
| 2092 void CodeGenerator::VisitBinaryOpNode(BinaryOpNode* node) { | 2114 void CodeGenerator::VisitBinaryOpNode(BinaryOpNode* node) { |
| 2093 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 2115 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 2094 // Operators "&&" and "||" cannot be overloaded, therefore inline them | 2116 // Operators "&&" and "||" cannot be overloaded, therefore inline them |
| 2095 // instead of calling the operator. | 2117 // instead of calling the operator. |
| 2096 GenerateLogicalAndOrOp(node); | 2118 GenerateLogicalAndOrOp(node); |
| 2097 return; | 2119 return; |
| 2098 } | 2120 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2177 | 2199 |
| 2178 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { | 2200 void CodeGenerator::VisitInstanceCallNode(InstanceCallNode* node) { |
| 2179 const int number_of_arguments = node->arguments()->length() + 1; | 2201 const int number_of_arguments = node->arguments()->length() + 1; |
| 2180 // Compute the receiver object and pass it as first argument to call. | 2202 // Compute the receiver object and pass it as first argument to call. |
| 2181 node->receiver()->Visit(this); | 2203 node->receiver()->Visit(this); |
| 2182 // Now compute rest of the arguments to the call. | 2204 // Now compute rest of the arguments to the call. |
| 2183 node->arguments()->Visit(this); | 2205 node->arguments()->Visit(this); |
| 2184 // Some method may be inlined using type feedback, therefore this may be a | 2206 // Some method may be inlined using type feedback, therefore this may be a |
| 2185 // deoptimization point. | 2207 // deoptimization point. |
| 2186 MarkDeoptPoint(node->id(), node->token_index()); | 2208 MarkDeoptPoint(node->id(), node->token_index()); |
| 2187 | 2209 const int kNumArgumentsChecked = 1; |
| 2188 GenerateInstanceCall(node->id(), | 2210 GenerateInstanceCall(node->id(), |
| 2189 node->token_index(), | 2211 node->token_index(), |
| 2190 node->function_name(), | 2212 node->function_name(), |
| 2191 number_of_arguments, | 2213 number_of_arguments, |
| 2192 node->arguments()->names()); | 2214 node->arguments()->names(), |
| 2215 kNumArgumentsChecked); |
| 2193 // Result is in EAX. | 2216 // Result is in EAX. |
| 2194 if (IsResultNeeded(node)) { | 2217 if (IsResultNeeded(node)) { |
| 2195 __ pushl(EAX); | 2218 __ pushl(EAX); |
| 2196 } | 2219 } |
| 2197 } | 2220 } |
| 2198 | 2221 |
| 2199 | 2222 |
| 2200 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { | 2223 void CodeGenerator::VisitStaticCallNode(StaticCallNode* node) { |
| 2201 node->arguments()->Visit(this); | 2224 node->arguments()->Visit(this); |
| 2202 __ LoadObject(ECX, node->function()); | 2225 __ LoadObject(ECX, node->function()); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2432 } | 2455 } |
| 2433 | 2456 |
| 2434 | 2457 |
| 2435 // Expects receiver on stack, returns result in EAX.. | 2458 // Expects receiver on stack, returns result in EAX.. |
| 2436 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, | 2459 void CodeGenerator::GenerateInstanceGetterCall(intptr_t node_id, |
| 2437 intptr_t token_index, | 2460 intptr_t token_index, |
| 2438 const String& field_name) { | 2461 const String& field_name) { |
| 2439 const String& getter_name = String::ZoneHandle(Field::GetterName(field_name)); | 2462 const String& getter_name = String::ZoneHandle(Field::GetterName(field_name)); |
| 2440 const int kNumberOfArguments = 1; | 2463 const int kNumberOfArguments = 1; |
| 2441 const Array& kNoArgumentNames = Array::Handle(); | 2464 const Array& kNoArgumentNames = Array::Handle(); |
| 2465 const int kNumArgumentsChecked = 1; |
| 2442 GenerateInstanceCall(node_id, | 2466 GenerateInstanceCall(node_id, |
| 2443 token_index, | 2467 token_index, |
| 2444 getter_name, | 2468 getter_name, |
| 2445 kNumberOfArguments, | 2469 kNumberOfArguments, |
| 2446 kNoArgumentNames); | 2470 kNoArgumentNames, |
| 2471 kNumArgumentsChecked); |
| 2447 } | 2472 } |
| 2448 | 2473 |
| 2449 | 2474 |
| 2450 // Call to the instance getter. | 2475 // Call to the instance getter. |
| 2451 void CodeGenerator::VisitInstanceGetterNode(InstanceGetterNode* node) { | 2476 void CodeGenerator::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 2452 node->receiver()->Visit(this); | 2477 node->receiver()->Visit(this); |
| 2453 MarkDeoptPoint(node->id(), node->token_index()); | 2478 MarkDeoptPoint(node->id(), node->token_index()); |
| 2454 GenerateInstanceGetterCall(node->id(), | 2479 GenerateInstanceGetterCall(node->id(), |
| 2455 node->token_index(), | 2480 node->token_index(), |
| 2456 node->field_name()); | 2481 node->field_name()); |
| 2457 if (IsResultNeeded(node)) { | 2482 if (IsResultNeeded(node)) { |
| 2458 __ pushl(EAX); | 2483 __ pushl(EAX); |
| 2459 } | 2484 } |
| 2460 } | 2485 } |
| 2461 | 2486 |
| 2462 | 2487 |
| 2463 // Expects receiver and value on stack. | 2488 // Expects receiver and value on stack. |
| 2464 void CodeGenerator::GenerateInstanceSetterCall(intptr_t node_id, | 2489 void CodeGenerator::GenerateInstanceSetterCall(intptr_t node_id, |
| 2465 intptr_t token_index, | 2490 intptr_t token_index, |
| 2466 const String& field_name) { | 2491 const String& field_name) { |
| 2467 const String& setter_name = String::ZoneHandle(Field::SetterName(field_name)); | 2492 const String& setter_name = String::ZoneHandle(Field::SetterName(field_name)); |
| 2468 const int kNumberOfArguments = 2; // receiver + value. | 2493 const int kNumberOfArguments = 2; // receiver + value. |
| 2469 const Array& kNoArgumentNames = Array::Handle(); | 2494 const Array& kNoArgumentNames = Array::Handle(); |
| 2495 const int kNumArgumentsChecked = 1; |
| 2470 GenerateInstanceCall(node_id, | 2496 GenerateInstanceCall(node_id, |
| 2471 token_index, | 2497 token_index, |
| 2472 setter_name, | 2498 setter_name, |
| 2473 kNumberOfArguments, | 2499 kNumberOfArguments, |
| 2474 kNoArgumentNames); | 2500 kNoArgumentNames, |
| 2501 kNumArgumentsChecked); |
| 2475 } | 2502 } |
| 2476 | 2503 |
| 2477 | 2504 |
| 2478 // The call to the instance setter implements the assignment to a field. | 2505 // The call to the instance setter implements the assignment to a field. |
| 2479 // The result of the assignment to a field is the value being stored. | 2506 // The result of the assignment to a field is the value being stored. |
| 2480 void CodeGenerator::VisitInstanceSetterNode(InstanceSetterNode* node) { | 2507 void CodeGenerator::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 2481 // Compute the receiver object and pass it as first argument to call. | 2508 // Compute the receiver object and pass it as first argument to call. |
| 2482 node->receiver()->Visit(this); | 2509 node->receiver()->Visit(this); |
| 2483 node->value()->Visit(this); | 2510 node->value()->Visit(this); |
| 2484 MarkDeoptPoint(node->id(), node->token_index()); | 2511 MarkDeoptPoint(node->id(), node->token_index()); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2743 message_buffer, kMessageBufferSize, | 2770 message_buffer, kMessageBufferSize, |
| 2744 format, args); | 2771 format, args); |
| 2745 va_end(args); | 2772 va_end(args); |
| 2746 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); | 2773 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 2747 UNREACHABLE(); | 2774 UNREACHABLE(); |
| 2748 } | 2775 } |
| 2749 | 2776 |
| 2750 } // namespace dart | 2777 } // namespace dart |
| 2751 | 2778 |
| 2752 #endif // defined TARGET_ARCH_IA32 | 2779 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |