| Index: runtime/vm/opt_code_generator_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/opt_code_generator_ia32.cc (revision 7300)
|
| +++ runtime/vm/opt_code_generator_ia32.cc (working copy)
|
| @@ -1355,128 +1355,6 @@
|
| }
|
|
|
|
|
| -// Debugging helper method, used in assert only.
|
| -static bool HaveSameClassesInICData(const ICData& a, const ICData& b) {
|
| - if (a.NumberOfChecks() != b.NumberOfChecks()) {
|
| - return false;
|
| - }
|
| - if (a.NumberOfChecks() == 0) {
|
| - return true;
|
| - }
|
| - if (a.num_args_tested() != b.num_args_tested()) {
|
| - return false;
|
| - }
|
| - // Only one-argument checks implemented.
|
| - ASSERT(a.num_args_tested() == 1);
|
| - Function& a_target = Function::Handle();
|
| - Function& b_target = Function::Handle();
|
| - Class& a_class = Class::Handle();
|
| - Class& b_class = Class::Handle();
|
| - for (intptr_t i = 0; i < a.NumberOfChecks(); i++) {
|
| - a.GetOneClassCheckAt(i, &a_class, &a_target);
|
| - bool found = false;
|
| - for (intptr_t n = 0; n < b.NumberOfChecks(); n++) {
|
| - b.GetOneClassCheckAt(n, &b_class, &b_target);
|
| - if ((a_class.raw() == b_class.raw())) {
|
| - found = true;
|
| - break;
|
| - }
|
| - }
|
| - if (!found) {
|
| - return false;
|
| - }
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -
|
| -void OptimizingCodeGenerator::VisitIncrOpInstanceFieldNode(
|
| - IncrOpInstanceFieldNode* node) {
|
| - ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
|
| - VisitLoadOne(node->receiver(), EBX);
|
| - __ pushl(EBX); // Duplicate receiver (preserve for setter).
|
| - const ICData& ic_data = node->ICDataAtId(node->id());
|
| - // Deoptimize if either this node has never been visited before or
|
| - // if the classes collected at getter and setter do not match (can happen
|
| - // if the increment is 'interrupted' by an exception).
|
| - if ((ic_data.NumberOfChecks() == 0) ||
|
| - !HaveSameClassesInICData(node->ICDataAtId(node->getter_id()),
|
| - node->ICDataAtId(node->setter_id()))) {
|
| - // Deoptimization point for this node is after receiver has been
|
| - // pushed twice on stack and before the getter (above) was executed.
|
| - DeoptimizationBlob* deopt_blob =
|
| - AddDeoptimizationBlob(node, EBX, kDeoptIncrInstance);
|
| - __ jmp(deopt_blob->label());
|
| - return;
|
| - }
|
| - InlineInstanceGetter(node,
|
| - node->getter_id(),
|
| - node->receiver(),
|
| - node->field_name(),
|
| - EBX);
|
| - // result is in EAX.
|
| - __ popl(EDX); // Get receiver.
|
| - const bool return_original_value = !node->prefix() && IsResultNeeded(node);
|
| - const Immediate one_value = Immediate(Smi::RawValue(1));
|
| - // EAX: Value.
|
| - // EDX: Receiver.
|
| - if (AtIdNodeHasClassAt(node, node->operator_id(), smi_class_, 0)) {
|
| - // Deoptimization point for this node is after receiver has been
|
| - // pushed twice on stack and before the getter (above) was executed.
|
| - DeoptimizationBlob* deopt_blob =
|
| - AddDeoptimizationBlob(node, EDX, EDX, kDeoptIncrInstanceOneClass);
|
| - if (return_original_value) {
|
| - // Preserve pre increment result.
|
| - __ movl(ECX, EAX);
|
| - }
|
| - __ testl(EAX, Immediate(kSmiTagMask));
|
| - __ j(NOT_ZERO, deopt_blob->label());
|
| - if (node->kind() == Token::kINCR) {
|
| - __ addl(EAX, one_value);
|
| - } else {
|
| - __ subl(EAX, one_value);
|
| - }
|
| - __ j(OVERFLOW, deopt_blob->label());
|
| - if (return_original_value) {
|
| - // Preserve as result.
|
| - __ pushl(ECX); // Preserve pre-increment value as result.
|
| - }
|
| - } else {
|
| - if (return_original_value) {
|
| - // Preserve as result.
|
| - __ pushl(EAX); // Preserve value as result.
|
| - }
|
| - __ pushl(EDX); // Preserve receiver.
|
| - __ pushl(EAX); // Left operand.
|
| - __ pushl(one_value); // Right operand.
|
| - const char* operator_name = (node->kind() == Token::kINCR) ? "+" : "-";
|
| - GenerateBinaryOperatorCall(node->operator_id(),
|
| - node->token_index(),
|
| - operator_name);
|
| - __ popl(EDX); // Restore receiver.
|
| - }
|
| - // EAX: Result of binary operation.
|
| - // EDX: receiver
|
| - if (IsResultNeeded(node) && node->prefix()) {
|
| - // Value stored into field is the result.
|
| - __ pushl(EAX);
|
| - }
|
| -
|
| - // This can never deoptimize since the checks are the same as in getter.
|
| - ASSERT(HaveSameClassesInICData(node->ICDataAtId(node->getter_id()),
|
| - node->ICDataAtId(node->setter_id())));
|
| - InlineInstanceSetter(node,
|
| - node->setter_id(),
|
| - node->receiver(),
|
| - node->field_name(),
|
| - EDX, // receiver
|
| - EAX); // value.
|
| -}
|
| -
|
| -
|
| -
|
| -
|
| -
|
| // Return offset of a field or -1 if field is not found.
|
| static intptr_t GetFieldOffset(const Class& field_class,
|
| const String& field_name) {
|
|
|