comparison src/share/vm/runtime/arguments.cpp @ 360:5d254928c888

Merge
author ysr
date Wed, 27 Aug 2008 11:20:46 -0700
parents 1ee8caae33af
children 032ddb9432ad
comparison
equal deleted inserted replaced
341:d60e4e6d7f72 360:5d254928c888
945 // If the user has chosen ParallelGCThreads > 0, we set UseParNewGC 945 // If the user has chosen ParallelGCThreads > 0, we set UseParNewGC
946 // if it's not explictly set or unset. If the user has chosen 946 // if it's not explictly set or unset. If the user has chosen
947 // UseParNewGC and not explicitly set ParallelGCThreads we 947 // UseParNewGC and not explicitly set ParallelGCThreads we
948 // set it, unless this is a single cpu machine. 948 // set it, unless this is a single cpu machine.
949 void Arguments::set_parnew_gc_flags() { 949 void Arguments::set_parnew_gc_flags() {
950 assert(!UseSerialGC && !UseParallelGC, "control point invariant"); 950 assert(!UseSerialGC && !UseParallelGC && !UseG1GC,
951 "control point invariant");
952 assert(UseParNewGC, "Error");
951 953
952 // Turn off AdaptiveSizePolicy by default for parnew until it is 954 // Turn off AdaptiveSizePolicy by default for parnew until it is
953 // complete. 955 // complete.
954 if (UseParNewGC && 956 if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
955 FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) {
956 FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false); 957 FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false);
957 } 958 }
958 959
959 if (FLAG_IS_DEFAULT(UseParNewGC) && ParallelGCThreads > 1) { 960 if (ParallelGCThreads == 0) {
960 FLAG_SET_DEFAULT(UseParNewGC, true);
961 } else if (UseParNewGC && ParallelGCThreads == 0) {
962 FLAG_SET_DEFAULT(ParallelGCThreads, 961 FLAG_SET_DEFAULT(ParallelGCThreads,
963 Abstract_VM_Version::parallel_worker_threads()); 962 Abstract_VM_Version::parallel_worker_threads());
964 if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) { 963 if (FLAG_IS_DEFAULT(ParallelGCThreads) && ParallelGCThreads == 1) {
965 FLAG_SET_DEFAULT(UseParNewGC, false); 964 FLAG_SET_DEFAULT(UseParNewGC, false);
966 } 965 }
992 // Adjust some sizes to suit CMS and/or ParNew needs; these work well on 991 // Adjust some sizes to suit CMS and/or ParNew needs; these work well on
993 // sparc/solaris for certain applications, but would gain from 992 // sparc/solaris for certain applications, but would gain from
994 // further optimization and tuning efforts, and would almost 993 // further optimization and tuning efforts, and would almost
995 // certainly gain from analysis of platform and environment. 994 // certainly gain from analysis of platform and environment.
996 void Arguments::set_cms_and_parnew_gc_flags() { 995 void Arguments::set_cms_and_parnew_gc_flags() {
997 if (UseSerialGC || UseParallelGC) { 996 assert(!UseSerialGC && !UseParallelGC, "Error");
998 return;
999 }
1000
1001 assert(UseConcMarkSweepGC, "CMS is expected to be on here"); 997 assert(UseConcMarkSweepGC, "CMS is expected to be on here");
1002 998
1003 // If we are using CMS, we prefer to UseParNewGC, 999 // If we are using CMS, we prefer to UseParNewGC,
1004 // unless explicitly forbidden. 1000 // unless explicitly forbidden.
1005 if (!UseParNewGC && FLAG_IS_DEFAULT(UseParNewGC)) { 1001 if (FLAG_IS_DEFAULT(UseParNewGC)) {
1006 FLAG_SET_ERGO(bool, UseParNewGC, true); 1002 FLAG_SET_ERGO(bool, UseParNewGC, true);
1007 } 1003 }
1008 1004
1009 // Turn off AdaptiveSizePolicy by default for cms until it is 1005 // Turn off AdaptiveSizePolicy by default for cms until it is
1010 // complete. 1006 // complete.
1180 // If no other collector is requested explicitly, 1176 // If no other collector is requested explicitly,
1181 // let the VM select the collector based on 1177 // let the VM select the collector based on
1182 // machine class and automatic selection policy. 1178 // machine class and automatic selection policy.
1183 if (!UseSerialGC && 1179 if (!UseSerialGC &&
1184 !UseConcMarkSweepGC && 1180 !UseConcMarkSweepGC &&
1181 !UseG1GC &&
1185 !UseParNewGC && 1182 !UseParNewGC &&
1186 !DumpSharedSpaces && 1183 !DumpSharedSpaces &&
1187 FLAG_IS_DEFAULT(UseParallelGC)) { 1184 FLAG_IS_DEFAULT(UseParallelGC)) {
1188 if (should_auto_select_low_pause_collector()) { 1185 if (should_auto_select_low_pause_collector()) {
1189 FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true); 1186 FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true);
1198 // Compressed Headers do not work with CMS, which uses a bit in the klass 1195 // Compressed Headers do not work with CMS, which uses a bit in the klass
1199 // field offset to determine free list chunk markers. 1196 // field offset to determine free list chunk markers.
1200 // Check that UseCompressedOops can be set with the max heap size allocated 1197 // Check that UseCompressedOops can be set with the max heap size allocated
1201 // by ergonomics. 1198 // by ergonomics.
1202 if (MaxHeapSize <= max_heap_for_compressed_oops()) { 1199 if (MaxHeapSize <= max_heap_for_compressed_oops()) {
1203 if (FLAG_IS_DEFAULT(UseCompressedOops)) { 1200 if (FLAG_IS_DEFAULT(UseCompressedOops) && !UseG1GC) {
1204 // Turn off until bug is fixed. 1201 // Turn off until bug is fixed.
1202 // the following line to return it to default status.
1205 // FLAG_SET_ERGO(bool, UseCompressedOops, true); 1203 // FLAG_SET_ERGO(bool, UseCompressedOops, true);
1204 } else if (UseCompressedOops && UseG1GC) {
1205 warning(" UseCompressedOops does not currently work with UseG1GC; switching off UseCompressedOops. ");
1206 FLAG_SET_DEFAULT(UseCompressedOops, false);
1206 } 1207 }
1207 } else { 1208 } else {
1208 if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) { 1209 if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
1209 // If specified, give a warning 1210 warning("Max heap size too large for Compressed Oops");
1210 if (UseConcMarkSweepGC){
1211 warning("Compressed Oops does not work with CMS");
1212 } else {
1213 warning(
1214 "Max heap size too large for Compressed Oops");
1215 }
1216 FLAG_SET_DEFAULT(UseCompressedOops, false); 1211 FLAG_SET_DEFAULT(UseCompressedOops, false);
1217 } 1212 }
1218 } 1213 }
1219 // Also checks that certain machines are slower with compressed oops 1214 // Also checks that certain machines are slower with compressed oops
1220 // in vm_version initialization code. 1215 // in vm_version initialization code.
1221 #endif // _LP64 1216 #endif // _LP64
1222 } 1217 }
1223 1218
1224 void Arguments::set_parallel_gc_flags() { 1219 void Arguments::set_parallel_gc_flags() {
1220 assert(UseParallelGC || UseParallelOldGC, "Error");
1225 // If parallel old was requested, automatically enable parallel scavenge. 1221 // If parallel old was requested, automatically enable parallel scavenge.
1226 if (UseParallelOldGC && !UseParallelGC && FLAG_IS_DEFAULT(UseParallelGC)) { 1222 if (UseParallelOldGC && !UseParallelGC && FLAG_IS_DEFAULT(UseParallelGC)) {
1227 FLAG_SET_DEFAULT(UseParallelGC, true); 1223 FLAG_SET_DEFAULT(UseParallelGC, true);
1228 } 1224 }
1229 1225
1231 // of the physical memory, up to a maximum of 1GB. 1227 // of the physical memory, up to a maximum of 1GB.
1232 if (UseParallelGC) { 1228 if (UseParallelGC) {
1233 FLAG_SET_ERGO(uintx, ParallelGCThreads, 1229 FLAG_SET_ERGO(uintx, ParallelGCThreads,
1234 Abstract_VM_Version::parallel_worker_threads()); 1230 Abstract_VM_Version::parallel_worker_threads());
1235 1231
1236 if (FLAG_IS_DEFAULT(MaxHeapSize)) { 1232 // PS is a server collector, setup the heap sizes accordingly.
1237 const uint64_t reasonable_fraction = 1233 set_server_heap_size();
1238 os::physical_memory() / DefaultMaxRAMFraction;
1239 const uint64_t maximum_size = (uint64_t)
1240 (FLAG_IS_DEFAULT(DefaultMaxRAM) && UseCompressedOops ?
1241 MIN2(max_heap_for_compressed_oops(), DefaultMaxRAM) :
1242 DefaultMaxRAM);
1243 size_t reasonable_max =
1244 (size_t) os::allocatable_physical_memory(reasonable_fraction);
1245 if (reasonable_max > maximum_size) {
1246 reasonable_max = maximum_size;
1247 }
1248 if (PrintGCDetails && Verbose) {
1249 // Cannot use gclog_or_tty yet.
1250 tty->print_cr(" Max heap size for server class platform "
1251 SIZE_FORMAT, reasonable_max);
1252 }
1253 // If the initial_heap_size has not been set with -Xms,
1254 // then set it as fraction of size of physical memory
1255 // respecting the maximum and minimum sizes of the heap.
1256 if (initial_heap_size() == 0) {
1257 const uint64_t reasonable_initial_fraction =
1258 os::physical_memory() / DefaultInitialRAMFraction;
1259 const size_t reasonable_initial =
1260 (size_t) os::allocatable_physical_memory(reasonable_initial_fraction);
1261 const size_t minimum_size = NewSize + OldSize;
1262 set_initial_heap_size(MAX2(MIN2(reasonable_initial, reasonable_max),
1263 minimum_size));
1264 // Currently the minimum size and the initial heap sizes are the same.
1265 set_min_heap_size(initial_heap_size());
1266 if (PrintGCDetails && Verbose) {
1267 // Cannot use gclog_or_tty yet.
1268 tty->print_cr(" Initial heap size for server class platform "
1269 SIZE_FORMAT, initial_heap_size());
1270 }
1271 } else {
1272 // An minimum size was specified on the command line. Be sure
1273 // that the maximum size is consistent.
1274 if (initial_heap_size() > reasonable_max) {
1275 reasonable_max = initial_heap_size();
1276 }
1277 }
1278 FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx) reasonable_max);
1279 }
1280
1281 // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the 1234 // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the
1282 // SurvivorRatio has been set, reset their default values to SurvivorRatio + 1235 // SurvivorRatio has been set, reset their default values to SurvivorRatio +
1283 // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger. 1236 // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger.
1284 // See CR 6362902 for details. 1237 // See CR 6362902 for details.
1285 if (!FLAG_IS_DEFAULT(SurvivorRatio)) { 1238 if (!FLAG_IS_DEFAULT(SurvivorRatio)) {
1303 } 1256 }
1304 } 1257 }
1305 } 1258 }
1306 } 1259 }
1307 1260
1261 void Arguments::set_g1_gc_flags() {
1262 assert(UseG1GC, "Error");
1263 // G1 is a server collector, setup the heap sizes accordingly.
1264 set_server_heap_size();
1265 #ifdef COMPILER1
1266 FastTLABRefill = false;
1267 #endif
1268 FLAG_SET_DEFAULT(ParallelGCThreads,
1269 Abstract_VM_Version::parallel_worker_threads());
1270 if (ParallelGCThreads == 0) {
1271 FLAG_SET_DEFAULT(ParallelGCThreads,
1272 Abstract_VM_Version::parallel_worker_threads
1273 ());
1274 }
1275 no_shared_spaces();
1276 }
1277
1278 void Arguments::set_server_heap_size() {
1279 if (FLAG_IS_DEFAULT(MaxHeapSize)) {
1280 const uint64_t reasonable_fraction =
1281 os::physical_memory() / DefaultMaxRAMFraction;
1282 const uint64_t maximum_size = (uint64_t)
1283 (FLAG_IS_DEFAULT(DefaultMaxRAM) && UseCompressedOops ?
1284 MIN2(max_heap_for_compressed_oops(), DefaultMaxRAM) :
1285 DefaultMaxRAM);
1286 size_t reasonable_max =
1287 (size_t) os::allocatable_physical_memory(reasonable_fraction);
1288 if (reasonable_max > maximum_size) {
1289 reasonable_max = maximum_size;
1290 }
1291 if (PrintGCDetails && Verbose) {
1292 // Cannot use gclog_or_tty yet.
1293 tty->print_cr(" Max heap size for server class platform "
1294 SIZE_FORMAT, reasonable_max);
1295 }
1296 // If the initial_heap_size has not been set with -Xms,
1297 // then set it as fraction of size of physical memory
1298 // respecting the maximum and minimum sizes of the heap.
1299 if (initial_heap_size() == 0) {
1300 const uint64_t reasonable_initial_fraction =
1301 os::physical_memory() / DefaultInitialRAMFraction;
1302 const size_t reasonable_initial =
1303 (size_t) os::allocatable_physical_memory(reasonable_initial_fraction);
1304 const size_t minimum_size = NewSize + OldSize;
1305 set_initial_heap_size(MAX2(MIN2(reasonable_initial, reasonable_max),
1306 minimum_size));
1307 // Currently the minimum size and the initial heap sizes are the same.
1308 set_min_heap_size(initial_heap_size());
1309 if (PrintGCDetails && Verbose) {
1310 // Cannot use gclog_or_tty yet.
1311 tty->print_cr(" Initial heap size for server class platform "
1312 SIZE_FORMAT, initial_heap_size());
1313 }
1314 } else {
1315 // A minimum size was specified on the command line. Be sure
1316 // that the maximum size is consistent.
1317 if (initial_heap_size() > reasonable_max) {
1318 reasonable_max = initial_heap_size();
1319 }
1320 }
1321 FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx) reasonable_max);
1322 }
1323 }
1324
1308 // This must be called after ergonomics because we want bytecode rewriting 1325 // This must be called after ergonomics because we want bytecode rewriting
1309 // if the server compiler is used, or if UseSharedSpaces is disabled. 1326 // if the server compiler is used, or if UseSharedSpaces is disabled.
1310 void Arguments::set_bytecode_flags() { 1327 void Arguments::set_bytecode_flags() {
1311 // Better not attempt to store into a read-only space. 1328 // Better not attempt to store into a read-only space.
1312 if (UseSharedSpaces) { 1329 if (UseSharedSpaces) {
1389 FLAG_SET_DEFAULT(UseSerialGC, true); 1406 FLAG_SET_DEFAULT(UseSerialGC, true);
1390 FLAG_SET_DEFAULT(UseParNewGC, false); 1407 FLAG_SET_DEFAULT(UseParNewGC, false);
1391 FLAG_SET_DEFAULT(UseConcMarkSweepGC, false); 1408 FLAG_SET_DEFAULT(UseConcMarkSweepGC, false);
1392 FLAG_SET_DEFAULT(UseParallelGC, false); 1409 FLAG_SET_DEFAULT(UseParallelGC, false);
1393 FLAG_SET_DEFAULT(UseParallelOldGC, false); 1410 FLAG_SET_DEFAULT(UseParallelOldGC, false);
1411 FLAG_SET_DEFAULT(UseG1GC, false);
1394 } 1412 }
1395 1413
1396 static bool verify_serial_gc_flags() { 1414 static bool verify_serial_gc_flags() {
1397 return (UseSerialGC && 1415 return (UseSerialGC &&
1398 !(UseParNewGC || UseConcMarkSweepGC || UseParallelGC || 1416 !(UseParNewGC || UseConcMarkSweepGC || UseG1GC ||
1399 UseParallelOldGC)); 1417 UseParallelGC || UseParallelOldGC));
1400 } 1418 }
1401 1419
1402 // Check consistency of GC selection 1420 // Check consistency of GC selection
1403 bool Arguments::check_gc_consistency() { 1421 bool Arguments::check_gc_consistency() {
1404 bool status = true; 1422 bool status = true;
1497 } 1515 }
1498 1516
1499 status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); 1517 status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
1500 1518
1501 // Check user specified sharing option conflict with Parallel GC 1519 // Check user specified sharing option conflict with Parallel GC
1502 bool cannot_share = (UseConcMarkSweepGC || UseParallelGC || 1520 bool cannot_share = (UseConcMarkSweepGC || UseG1GC || UseParNewGC ||
1503 UseParallelOldGC || UseParNewGC || 1521 UseParallelGC || UseParallelOldGC ||
1504 SOLARIS_ONLY(UseISM) NOT_SOLARIS(UseLargePages)); 1522 SOLARIS_ONLY(UseISM) NOT_SOLARIS(UseLargePages));
1505 1523
1506 if (cannot_share) { 1524 if (cannot_share) {
1507 // Either force sharing on by forcing the other options off, or 1525 // Either force sharing on by forcing the other options off, or
1508 // force sharing off. 1526 // force sharing off.
1537 if (!UseConcMarkSweepGC) { 1555 if (!UseConcMarkSweepGC) {
1538 jio_fprintf(defaultStream::error_stream(), 1556 jio_fprintf(defaultStream::error_stream(),
1539 "error: invalid argument combination.\n" 1557 "error: invalid argument combination.\n"
1540 "The CMS collector (-XX:+UseConcMarkSweepGC) must be " 1558 "The CMS collector (-XX:+UseConcMarkSweepGC) must be "
1541 "selected in order\nto use CMSIncrementalMode.\n"); 1559 "selected in order\nto use CMSIncrementalMode.\n");
1542 status = false;
1543 } else if (!UseTLAB) {
1544 jio_fprintf(defaultStream::error_stream(),
1545 "error: CMSIncrementalMode requires thread-local "
1546 "allocation buffers\n(-XX:+UseTLAB).\n");
1547 status = false; 1560 status = false;
1548 } else { 1561 } else {
1549 status = status && verify_percentage(CMSIncrementalDutyCycle, 1562 status = status && verify_percentage(CMSIncrementalDutyCycle,
1550 "CMSIncrementalDutyCycle"); 1563 "CMSIncrementalDutyCycle");
1551 status = status && verify_percentage(CMSIncrementalDutyCycleMin, 1564 status = status && verify_percentage(CMSIncrementalDutyCycleMin,
1560 // CMSInitiatingOccupancyFraction to 1 so icms can initiate cycles early. 1573 // CMSInitiatingOccupancyFraction to 1 so icms can initiate cycles early.
1561 if (CMSInitiatingOccupancyFraction < 0) { 1574 if (CMSInitiatingOccupancyFraction < 0) {
1562 FLAG_SET_DEFAULT(CMSInitiatingOccupancyFraction, 1); 1575 FLAG_SET_DEFAULT(CMSInitiatingOccupancyFraction, 1);
1563 } 1576 }
1564 } 1577 }
1565 }
1566
1567 if (UseNUMA && !UseTLAB) {
1568 jio_fprintf(defaultStream::error_stream(),
1569 "error: NUMA allocator (-XX:+UseNUMA) requires thread-local "
1570 "allocation\nbuffers (-XX:+UseTLAB).\n");
1571 status = false;
1572 } 1578 }
1573 1579
1574 // CMS space iteration, which FLSVerifyAllHeapreferences entails, 1580 // CMS space iteration, which FLSVerifyAllHeapreferences entails,
1575 // insists that we hold the requisite locks so that the iteration is 1581 // insists that we hold the requisite locks so that the iteration is
1576 // MT-safe. For the verification at start-up and shut-down, we don't 1582 // MT-safe. For the verification at start-up and shut-down, we don't
2357 // Java heap and the code cache. 2363 // Java heap and the code cache.
2358 FLAG_SET_DEFAULT(UseLargePages, false); 2364 FLAG_SET_DEFAULT(UseLargePages, false);
2359 SOLARIS_ONLY(FLAG_SET_DEFAULT(UseMPSS, false)); 2365 SOLARIS_ONLY(FLAG_SET_DEFAULT(UseMPSS, false));
2360 SOLARIS_ONLY(FLAG_SET_DEFAULT(UseISM, false)); 2366 SOLARIS_ONLY(FLAG_SET_DEFAULT(UseISM, false));
2361 } 2367 }
2368
2362 #else 2369 #else
2363 if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) { 2370 if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) {
2364 FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1); 2371 FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1);
2372 }
2373 // Temporary disable bulk zeroing reduction with G1. See CR 6627983.
2374 if (UseG1GC) {
2375 FLAG_SET_DEFAULT(ReduceBulkZeroing, false);
2365 } 2376 }
2366 #endif 2377 #endif
2367 2378
2368 if (!check_vm_args_consistency()) { 2379 if (!check_vm_args_consistency()) {
2369 return JNI_ERR; 2380 return JNI_ERR;
2515 logOption(tail); 2526 logOption(tail);
2516 } 2527 }
2517 } 2528 }
2518 } 2529 }
2519 2530
2531
2520 // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS 2532 // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
2521 jint result = parse_vm_init_args(args); 2533 jint result = parse_vm_init_args(args);
2522 if (result != JNI_OK) { 2534 if (result != JNI_OK) {
2523 return result; 2535 return result;
2536 }
2537
2538 // These are hacks until G1 is fully supported and tested
2539 // but lets you force -XX:+UseG1GC in PRT and get it where it (mostly) works
2540 if (UseG1GC) {
2541 if (UseConcMarkSweepGC || UseParNewGC || UseParallelGC || UseParallelOldGC || UseSerialGC) {
2542 #ifndef PRODUCT
2543 tty->print_cr("-XX:+UseG1GC is incompatible with other collectors, using UseG1GC");
2544 #endif // PRODUCT
2545 UseConcMarkSweepGC = false;
2546 UseParNewGC = false;
2547 UseParallelGC = false;
2548 UseParallelOldGC = false;
2549 UseSerialGC = false;
2550 }
2551 no_shared_spaces();
2524 } 2552 }
2525 2553
2526 #ifndef PRODUCT 2554 #ifndef PRODUCT
2527 if (TraceBytecodesAt != 0) { 2555 if (TraceBytecodesAt != 0) {
2528 TraceBytecodes = true; 2556 TraceBytecodes = true;
2565 // Set some flags for CMS 2593 // Set some flags for CMS
2566 set_cms_and_parnew_gc_flags(); 2594 set_cms_and_parnew_gc_flags();
2567 } else if (UseParNewGC) { 2595 } else if (UseParNewGC) {
2568 // Set some flags for ParNew 2596 // Set some flags for ParNew
2569 set_parnew_gc_flags(); 2597 set_parnew_gc_flags();
2598 }
2599 // Temporary; make the "if" an "else-if" before
2600 // we integrate G1. XXX
2601 if (UseG1GC) {
2602 // Set some flags for garbage-first, if needed.
2603 set_g1_gc_flags();
2570 } 2604 }
2571 2605
2572 #ifdef SERIALGC 2606 #ifdef SERIALGC
2573 assert(verify_serial_gc_flags(), "SerialGC unset"); 2607 assert(verify_serial_gc_flags(), "SerialGC unset");
2574 #endif // SERIALGC 2608 #endif // SERIALGC