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

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

Issue 10354019: Removing all incr-op nodes. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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
« no previous file with comments | « runtime/vm/opt_code_generator_ia32.h ('k') | runtime/vm/parser.cc » ('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/opt_code_generator.h" 8 #include "vm/opt_code_generator.h"
9 9
10 #include "vm/assembler_macros.h" 10 #include "vm/assembler_macros.h"
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 node->left(), 1348 node->left(),
1349 node->id(), 1349 node->id(),
1350 node->token_index(), 1350 node->token_index(),
1351 number_of_arguments, 1351 number_of_arguments,
1352 no_optional_argument_names); 1352 no_optional_argument_names);
1353 HandleResult(node, EAX); 1353 HandleResult(node, EAX);
1354 return; 1354 return;
1355 } 1355 }
1356 1356
1357 1357
1358 // Debugging helper method, used in assert only.
1359 static bool HaveSameClassesInICData(const ICData& a, const ICData& b) {
1360 if (a.NumberOfChecks() != b.NumberOfChecks()) {
1361 return false;
1362 }
1363 if (a.NumberOfChecks() == 0) {
1364 return true;
1365 }
1366 if (a.num_args_tested() != b.num_args_tested()) {
1367 return false;
1368 }
1369 // Only one-argument checks implemented.
1370 ASSERT(a.num_args_tested() == 1);
1371 Function& a_target = Function::Handle();
1372 Function& b_target = Function::Handle();
1373 Class& a_class = Class::Handle();
1374 Class& b_class = Class::Handle();
1375 for (intptr_t i = 0; i < a.NumberOfChecks(); i++) {
1376 a.GetOneClassCheckAt(i, &a_class, &a_target);
1377 bool found = false;
1378 for (intptr_t n = 0; n < b.NumberOfChecks(); n++) {
1379 b.GetOneClassCheckAt(n, &b_class, &b_target);
1380 if ((a_class.raw() == b_class.raw())) {
1381 found = true;
1382 break;
1383 }
1384 }
1385 if (!found) {
1386 return false;
1387 }
1388 }
1389 return true;
1390 }
1391
1392
1393 void OptimizingCodeGenerator::VisitIncrOpInstanceFieldNode(
1394 IncrOpInstanceFieldNode* node) {
1395 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
1396 VisitLoadOne(node->receiver(), EBX);
1397 __ pushl(EBX); // Duplicate receiver (preserve for setter).
1398 const ICData& ic_data = node->ICDataAtId(node->id());
1399 // Deoptimize if either this node has never been visited before or
1400 // if the classes collected at getter and setter do not match (can happen
1401 // if the increment is 'interrupted' by an exception).
1402 if ((ic_data.NumberOfChecks() == 0) ||
1403 !HaveSameClassesInICData(node->ICDataAtId(node->getter_id()),
1404 node->ICDataAtId(node->setter_id()))) {
1405 // Deoptimization point for this node is after receiver has been
1406 // pushed twice on stack and before the getter (above) was executed.
1407 DeoptimizationBlob* deopt_blob =
1408 AddDeoptimizationBlob(node, EBX, kDeoptIncrInstance);
1409 __ jmp(deopt_blob->label());
1410 return;
1411 }
1412 InlineInstanceGetter(node,
1413 node->getter_id(),
1414 node->receiver(),
1415 node->field_name(),
1416 EBX);
1417 // result is in EAX.
1418 __ popl(EDX); // Get receiver.
1419 const bool return_original_value = !node->prefix() && IsResultNeeded(node);
1420 const Immediate one_value = Immediate(Smi::RawValue(1));
1421 // EAX: Value.
1422 // EDX: Receiver.
1423 if (AtIdNodeHasClassAt(node, node->operator_id(), smi_class_, 0)) {
1424 // Deoptimization point for this node is after receiver has been
1425 // pushed twice on stack and before the getter (above) was executed.
1426 DeoptimizationBlob* deopt_blob =
1427 AddDeoptimizationBlob(node, EDX, EDX, kDeoptIncrInstanceOneClass);
1428 if (return_original_value) {
1429 // Preserve pre increment result.
1430 __ movl(ECX, EAX);
1431 }
1432 __ testl(EAX, Immediate(kSmiTagMask));
1433 __ j(NOT_ZERO, deopt_blob->label());
1434 if (node->kind() == Token::kINCR) {
1435 __ addl(EAX, one_value);
1436 } else {
1437 __ subl(EAX, one_value);
1438 }
1439 __ j(OVERFLOW, deopt_blob->label());
1440 if (return_original_value) {
1441 // Preserve as result.
1442 __ pushl(ECX); // Preserve pre-increment value as result.
1443 }
1444 } else {
1445 if (return_original_value) {
1446 // Preserve as result.
1447 __ pushl(EAX); // Preserve value as result.
1448 }
1449 __ pushl(EDX); // Preserve receiver.
1450 __ pushl(EAX); // Left operand.
1451 __ pushl(one_value); // Right operand.
1452 const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
1453 GenerateBinaryOperatorCall(node->operator_id(),
1454 node->token_index(),
1455 operator_name);
1456 __ popl(EDX); // Restore receiver.
1457 }
1458 // EAX: Result of binary operation.
1459 // EDX: receiver
1460 if (IsResultNeeded(node) && node->prefix()) {
1461 // Value stored into field is the result.
1462 __ pushl(EAX);
1463 }
1464
1465 // This can never deoptimize since the checks are the same as in getter.
1466 ASSERT(HaveSameClassesInICData(node->ICDataAtId(node->getter_id()),
1467 node->ICDataAtId(node->setter_id())));
1468 InlineInstanceSetter(node,
1469 node->setter_id(),
1470 node->receiver(),
1471 node->field_name(),
1472 EDX, // receiver
1473 EAX); // value.
1474 }
1475
1476
1477
1478
1479
1480 // Return offset of a field or -1 if field is not found. 1358 // Return offset of a field or -1 if field is not found.
1481 static intptr_t GetFieldOffset(const Class& field_class, 1359 static intptr_t GetFieldOffset(const Class& field_class,
1482 const String& field_name) { 1360 const String& field_name) {
1483 Class& cls = Class::Handle(field_class.raw()); 1361 Class& cls = Class::Handle(field_class.raw());
1484 Field& field = Field::Handle(); 1362 Field& field = Field::Handle();
1485 while (!cls.IsNull()) { 1363 while (!cls.IsNull()) {
1486 field = cls.LookupInstanceField(field_name); 1364 field = cls.LookupInstanceField(field_name);
1487 if (!field.IsNull()) { 1365 if (!field.IsNull()) {
1488 return field.Offset(); 1366 return field.Offset();
1489 } 1367 }
(...skipping 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after
3035 } 2913 }
3036 } 2914 }
3037 // TODO(srdjan): Implement unary kSUB (negate) Mint. 2915 // TODO(srdjan): Implement unary kSUB (negate) Mint.
3038 CodeGenerator::VisitUnaryOpNode(node); 2916 CodeGenerator::VisitUnaryOpNode(node);
3039 } 2917 }
3040 2918
3041 2919
3042 } // namespace dart 2920 } // namespace dart
3043 2921
3044 #endif // defined TARGET_ARCH_IA32 2922 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/opt_code_generator_ia32.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698