Revision f230a1cf deps/v8/src/x64/lithium-x64.cc

View differences:

deps/v8/src/x64/lithium-x64.cc
353 353
}
354 354

  
355 355

  
356
int LPlatformChunk::GetNextSpillIndex(bool is_double) {
356
int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
357 357
  return spill_slot_count_++;
358 358
}
359 359

  
360 360

  
361
LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) {
361
LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
362 362
  // All stack slots are Double stack slots on x64.
363 363
  // Alternatively, at some point, start using half-size
364 364
  // stack slots for int32 values.
365
  int index = GetNextSpillIndex(is_double);
366
  if (is_double) {
365
  int index = GetNextSpillIndex(kind);
366
  if (kind == DOUBLE_REGISTERS) {
367 367
    return LDoubleStackSlot::Create(index, zone());
368 368
  } else {
369
    ASSERT(kind == GENERAL_REGISTERS);
369 370
    return LStackSlot::Create(index, zone());
370 371
  }
371 372
}
......
445 446
  // which will be subsumed into this frame.
446 447
  if (graph()->has_osr()) {
447 448
    for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) {
448
      chunk_->GetNextSpillIndex(false);
449
      chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
449 450
    }
450 451
  }
451 452

  
......
664 665

  
665 666
LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
666 667
  ASSERT(!instr->HasPointerMap());
667
  instr->set_pointer_map(new(zone()) LPointerMap(position_, zone()));
668
  instr->set_pointer_map(new(zone()) LPointerMap(zone()));
668 669
  return instr;
669 670
}
670 671

  
......
719 720

  
720 721
LInstruction* LChunkBuilder::DoShift(Token::Value op,
721 722
                                     HBitwiseBinaryOperation* instr) {
722
  if (instr->representation().IsTagged()) {
723
    ASSERT(instr->left()->representation().IsTagged());
724
    ASSERT(instr->right()->representation().IsTagged());
723
  if (instr->representation().IsSmiOrInteger32()) {
724
    ASSERT(instr->left()->representation().Equals(instr->representation()));
725
    ASSERT(instr->right()->representation().Equals(instr->representation()));
726
    LOperand* left = UseRegisterAtStart(instr->left());
725 727

  
726
    LOperand* left = UseFixed(instr->left(), rdx);
727
    LOperand* right = UseFixed(instr->right(), rax);
728
    LArithmeticT* result = new(zone()) LArithmeticT(op, left, right);
729
    return MarkAsCall(DefineFixed(result, rax), instr);
730
  }
728
    HValue* right_value = instr->right();
729
    LOperand* right = NULL;
730
    int constant_value = 0;
731
    if (right_value->IsConstant()) {
732
      HConstant* constant = HConstant::cast(right_value);
733
      right = chunk_->DefineConstantOperand(constant);
734
      constant_value = constant->Integer32Value() & 0x1f;
735
    } else {
736
      right = UseFixed(right_value, rcx);
737
    }
731 738

  
732
  ASSERT(instr->representation().IsSmiOrInteger32());
733
  ASSERT(instr->left()->representation().Equals(instr->representation()));
734
  ASSERT(instr->right()->representation().Equals(instr->representation()));
735
  LOperand* left = UseRegisterAtStart(instr->left());
739
    // Shift operations can only deoptimize if we do a logical shift by 0 and
740
    // the result cannot be truncated to int32.
741
    bool does_deopt = false;
742
    if (op == Token::SHR && constant_value == 0) {
743
      if (FLAG_opt_safe_uint32_operations) {
744
        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
745
      } else {
746
        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
747
      }
748
    }
736 749

  
737
  HValue* right_value = instr->right();
738
  LOperand* right = NULL;
739
  int constant_value = 0;
740
  if (right_value->IsConstant()) {
741
    HConstant* constant = HConstant::cast(right_value);
742
    right = chunk_->DefineConstantOperand(constant);
743
    constant_value = constant->Integer32Value() & 0x1f;
750
    LInstruction* result =
751
        DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt));
752
    return does_deopt ? AssignEnvironment(result) : result;
744 753
  } else {
745
    right = UseFixed(right_value, rcx);
746
  }
747

  
748
  // Shift operations can only deoptimize if we do a logical shift by 0 and
749
  // the result cannot be truncated to int32.
750
  bool does_deopt = false;
751
  if (op == Token::SHR && constant_value == 0) {
752
    if (FLAG_opt_safe_uint32_operations) {
753
      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
754
    } else {
755
      does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
756
    }
754
    return DoArithmeticT(op, instr);
757 755
  }
758

  
759
  LInstruction* result =
760
      DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt));
761
  return does_deopt ? AssignEnvironment(result) : result;
762 756
}
763 757

  
764 758

  
......
767 761
  ASSERT(instr->representation().IsDouble());
768 762
  ASSERT(instr->left()->representation().IsDouble());
769 763
  ASSERT(instr->right()->representation().IsDouble());
770
  ASSERT(op != Token::MOD);
771
  LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
772
  LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
773
  LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
774
  return DefineSameAsFirst(result);
764
  if (op == Token::MOD) {
765
    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
766
    LOperand* right = UseFixedDouble(instr->BetterRightOperand(), xmm1);
767
    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
768
    return MarkAsCall(DefineSameAsFirst(result), instr);
769
  } else {
770
    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
771
    LOperand* right = UseRegisterAtStart(instr->BetterRightOperand());
772
    LArithmeticD* result = new(zone()) LArithmeticD(op, left, right);
773
    return DefineSameAsFirst(result);
774
  }
775 775
}
776 776

  
777 777

  
778 778
LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
779
                                           HArithmeticBinaryOperation* instr) {
780
  ASSERT(op == Token::ADD ||
781
         op == Token::DIV ||
782
         op == Token::MOD ||
783
         op == Token::MUL ||
784
         op == Token::SUB);
779
                                           HBinaryOperation* instr) {
785 780
  HValue* left = instr->left();
786 781
  HValue* right = instr->right();
787 782
  ASSERT(left->representation().IsTagged());
......
864 859
void LChunkBuilder::VisitInstruction(HInstruction* current) {
865 860
  HInstruction* old_current = current_instruction_;
866 861
  current_instruction_ = current;
867
  if (current->has_position()) position_ = current->position();
868
  LInstruction* instr = current->CompileToLithium(this);
862

  
863
  LInstruction* instr = NULL;
864
  if (current->CanReplaceWithDummyUses()) {
865
    HValue* first_operand = current->OperandCount() == 0
866
        ? graph()->GetConstant1()
867
        : current->OperandAt(0);
868
    instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand)));
869
    for (int i = 1; i < current->OperandCount(); ++i) {
870
      LInstruction* dummy =
871
          new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
872
      dummy->set_hydrogen_value(current);
873
      chunk_->AddInstruction(dummy, current_block_);
874
    }
875
  } else {
876
    instr = current->CompileToLithium(this);
877
  }
878

  
879
  argument_count_ += current->argument_delta();
880
  ASSERT(argument_count_ >= 0);
869 881

  
870 882
  if (instr != NULL) {
883
    // Associate the hydrogen instruction first, since we may need it for
884
    // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below.
885
    instr->set_hydrogen_value(current);
886

  
871 887
#if DEBUG
872 888
    // Make sure that the lithium instruction has either no fixed register
873 889
    // constraints in temps or the result OR no uses that are only used at
......
897 913
    }
898 914
#endif
899 915

  
900
    instr->set_position(position_);
901 916
    if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
902 917
      instr = AssignPointerMap(instr);
903 918
    }
904 919
    if (FLAG_stress_environments && !instr->HasEnvironment()) {
905 920
      instr = AssignEnvironment(instr);
906 921
    }
907
    instr->set_hydrogen_value(current);
908 922
    chunk_->AddInstruction(instr, current_block_);
909 923
  }
910 924
  current_instruction_ = old_current;
......
996 1010

  
997 1011

  
998 1012
LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
999
  return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
1013
  return new(zone()) LGoto(instr->FirstSuccessor());
1000 1014
}
1001 1015

  
1002 1016

  
......
1006 1020

  
1007 1021

  
1008 1022
LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1009
  HValue* value = instr->value();
1010
  if (value->EmitAtUses()) {
1011
    ASSERT(value->IsConstant());
1012
    ASSERT(!value->representation().IsDouble());
1013
    HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
1014
        ? instr->FirstSuccessor()
1015
        : instr->SecondSuccessor();
1016
    return new(zone()) LGoto(successor->block_id());
1017
  }
1023
  LInstruction* goto_instr = CheckElideControlInstruction(instr);
1024
  if (goto_instr != NULL) return goto_instr;
1018 1025

  
1026
  HValue* value = instr->value();
1019 1027
  LBranch* result = new(zone()) LBranch(UseRegister(value));
1020 1028
  // Tagged values that are not known smis or booleans require a
1021 1029
  // deoptimization environment. If the instruction is generic no
......
1067 1075
}
1068 1076

  
1069 1077

  
1070
LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) {
1071
  LOperand* object = UseRegisterAtStart(instr->object());
1072
  return DefineAsRegister(new(zone()) LInstanceSize(object));
1073
}
1074

  
1075

  
1076 1078
LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
1077 1079
  LOperand* receiver = UseRegister(instr->receiver());
1078 1080
  LOperand* function = UseRegisterAtStart(instr->function());
......
1095 1097

  
1096 1098

  
1097 1099
LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1098
  ++argument_count_;
1099 1100
  LOperand* argument = UseOrConstant(instr->argument());
1100 1101
  return new(zone()) LPushArgument(argument);
1101 1102
}
......
1161 1162

  
1162 1163
LInstruction* LChunkBuilder::DoCallConstantFunction(
1163 1164
    HCallConstantFunction* instr) {
1164
  argument_count_ -= instr->argument_count();
1165 1165
  return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, rax), instr);
1166 1166
}
1167 1167

  
1168 1168

  
1169 1169
LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1170 1170
  LOperand* function = UseFixed(instr->function(), rdi);
1171
  argument_count_ -= instr->argument_count();
1172 1171
  LInvokeFunction* result = new(zone()) LInvokeFunction(function);
1173 1172
  return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1174 1173
}
......
1215 1214

  
1216 1215

  
1217 1216
LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1218
  LOperand* input = UseFixedDouble(instr->value(), xmm1);
1217
  ASSERT(instr->representation().IsDouble());
1218
  ASSERT(instr->value()->representation().IsDouble());
1219
  LOperand* input = UseRegisterAtStart(instr->value());
1219 1220
  LMathLog* result = new(zone()) LMathLog(input);
1220
  return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
1221
  return DefineSameAsFirst(result);
1221 1222
}
1222 1223

  
1223 1224

  
......
1270 1271
LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1271 1272
  ASSERT(instr->key()->representation().IsTagged());
1272 1273
  LOperand* key = UseFixed(instr->key(), rcx);
1273
  argument_count_ -= instr->argument_count();
1274 1274
  LCallKeyed* result = new(zone()) LCallKeyed(key);
1275 1275
  return MarkAsCall(DefineFixed(result, rax), instr);
1276 1276
}
1277 1277

  
1278 1278

  
1279 1279
LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1280
  argument_count_ -= instr->argument_count();
1281 1280
  return MarkAsCall(DefineFixed(new(zone()) LCallNamed, rax), instr);
1282 1281
}
1283 1282

  
1284 1283

  
1285 1284
LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
1286
  argument_count_ -= instr->argument_count();
1287 1285
  return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, rax), instr);
1288 1286
}
1289 1287

  
1290 1288

  
1291 1289
LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1292
  argument_count_ -= instr->argument_count();
1293 1290
  return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, rax), instr);
1294 1291
}
1295 1292

  
1296 1293

  
1297 1294
LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1298 1295
  LOperand* constructor = UseFixed(instr->constructor(), rdi);
1299
  argument_count_ -= instr->argument_count();
1300 1296
  LCallNew* result = new(zone()) LCallNew(constructor);
1301 1297
  return MarkAsCall(DefineFixed(result, rax), instr);
1302 1298
}
......
1304 1300

  
1305 1301
LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
1306 1302
  LOperand* constructor = UseFixed(instr->constructor(), rdi);
1307
  argument_count_ -= instr->argument_count();
1308 1303
  LCallNewArray* result = new(zone()) LCallNewArray(constructor);
1309 1304
  return MarkAsCall(DefineFixed(result, rax), instr);
1310 1305
}
......
1312 1307

  
1313 1308
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1314 1309
  LOperand* function = UseFixed(instr->function(), rdi);
1315
  argument_count_ -= instr->argument_count();
1316 1310
  LCallFunction* result = new(zone()) LCallFunction(function);
1317 1311
  return MarkAsCall(DefineFixed(result, rax), instr);
1318 1312
}
1319 1313

  
1320 1314

  
1321 1315
LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1322
  argument_count_ -= instr->argument_count();
1323 1316
  return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, rax), instr);
1324 1317
}
1325 1318

  
......
1348 1341
  if (instr->representation().IsSmiOrInteger32()) {
1349 1342
    ASSERT(instr->left()->representation().Equals(instr->representation()));
1350 1343
    ASSERT(instr->right()->representation().Equals(instr->representation()));
1344
    ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32));
1351 1345

  
1352 1346
    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
1353 1347
    LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
1354 1348
    return DefineSameAsFirst(new(zone()) LBitI(left, right));
1355 1349
  } else {
1356
    ASSERT(instr->representation().IsTagged());
1357
    ASSERT(instr->left()->representation().IsTagged());
1358
    ASSERT(instr->right()->representation().IsTagged());
1359

  
1360
    LOperand* left = UseFixed(instr->left(), rdx);
1361
    LOperand* right = UseFixed(instr->right(), rax);
1362
    LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right);
1363
    return MarkAsCall(DefineFixed(result, rax), instr);
1350
    return DoArithmeticT(instr->op(), instr);
1364 1351
  }
1365 1352
}
1366 1353

  
1367 1354

  
1368 1355
LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1369
  if (instr->representation().IsDouble()) {
1370
    return DoArithmeticD(Token::DIV, instr);
1371
  } else if (instr->representation().IsSmiOrInteger32()) {
1356
  if (instr->representation().IsSmiOrInteger32()) {
1372 1357
    ASSERT(instr->left()->representation().Equals(instr->representation()));
1373 1358
    ASSERT(instr->right()->representation().Equals(instr->representation()));
1374 1359
    if (instr->HasPowerOf2Divisor()) {
......
1385 1370
    LOperand* divisor = UseRegister(instr->right());
1386 1371
    LDivI* result = new(zone()) LDivI(dividend, divisor, temp);
1387 1372
    return AssignEnvironment(DefineFixed(result, rax));
1373
  } else if (instr->representation().IsDouble()) {
1374
    return DoArithmeticD(Token::DIV, instr);
1388 1375
  } else {
1389
    ASSERT(instr->representation().IsTagged());
1390 1376
    return DoArithmeticT(Token::DIV, instr);
1391 1377
  }
1392 1378
}
......
1485 1471
          ? AssignEnvironment(result)
1486 1472
          : result;
1487 1473
    }
1488
  } else if (instr->representation().IsTagged()) {
1489
    return DoArithmeticT(Token::MOD, instr);
1474
  } else if (instr->representation().IsDouble()) {
1475
    return DoArithmeticD(Token::MOD, instr);
1490 1476
  } else {
1491
    ASSERT(instr->representation().IsDouble());
1492
    // We call a C function for double modulo. It can't trigger a GC. We need to
1493
    // use fixed result register for the call.
1494
    // TODO(fschneider): Allow any register as input registers.
1495
    LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD,
1496
                                                 UseFixedDouble(left, xmm2),
1497
                                                 UseFixedDouble(right, xmm1));
1498
    return MarkAsCall(DefineFixedDouble(mod, xmm1), instr);
1477
    return DoArithmeticT(Token::MOD, instr);
1499 1478
  }
1500 1479
}
1501 1480

  
......
1515 1494
  } else if (instr->representation().IsDouble()) {
1516 1495
    return DoArithmeticD(Token::MUL, instr);
1517 1496
  } else {
1518
    ASSERT(instr->representation().IsTagged());
1519 1497
    return DoArithmeticT(Token::MUL, instr);
1520 1498
  }
1521 1499
}
......
1536 1514
  } else if (instr->representation().IsDouble()) {
1537 1515
    return DoArithmeticD(Token::SUB, instr);
1538 1516
  } else {
1539
    ASSERT(instr->representation().IsTagged());
1540 1517
    return DoArithmeticT(Token::SUB, instr);
1541 1518
  }
1542 1519
}
......
1568 1545
  } else if (instr->representation().IsDouble()) {
1569 1546
    return DoArithmeticD(Token::ADD, instr);
1570 1547
  } else {
1571
    ASSERT(instr->representation().IsTagged());
1572 1548
    return DoArithmeticT(Token::ADD, instr);
1573 1549
  }
1574 1550
  return NULL;
......
1662 1638

  
1663 1639
LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1664 1640
    HCompareObjectEqAndBranch* instr) {
1641
  LInstruction* goto_instr = CheckElideControlInstruction(instr);
1642
  if (goto_instr != NULL) return goto_instr;
1665 1643
  LOperand* left = UseRegisterAtStart(instr->left());
1666 1644
  LOperand* right = UseRegisterOrConstantAtStart(instr->right());
1667 1645
  return new(zone()) LCmpObjectEqAndBranch(left, right);
......
1670 1648

  
1671 1649
LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
1672 1650
    HCompareHoleAndBranch* instr) {
1673
  LOperand* object = UseRegisterAtStart(instr->object());
1674
  return new(zone()) LCmpHoleAndBranch(object);
1651
  LOperand* value = UseRegisterAtStart(instr->value());
1652
  return new(zone()) LCmpHoleAndBranch(value);
1675 1653
}
1676 1654

  
1677 1655

  
......
1803 1781
}
1804 1782

  
1805 1783

  
1784
LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1785
  // The control instruction marking the end of a block that completed
1786
  // abruptly (e.g., threw an exception).  There is nothing specific to do.
1787
  return NULL;
1788
}
1789

  
1790

  
1806 1791
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1807 1792
  LOperand* value = UseFixed(instr->value(), rax);
1808 1793
  return MarkAsCall(new(zone()) LThrow(value), instr);
......
1837 1822
  // building a stack frame.
1838 1823
  if (from.IsTagged()) {
1839 1824
    if (to.IsDouble()) {
1840
      info()->MarkAsDeferredCalling();
1841 1825
      LOperand* value = UseRegister(instr->value());
1842 1826
      LNumberUntagD* res = new(zone()) LNumberUntagD(value);
1843 1827
      return AssignEnvironment(DefineAsRegister(res));
......
1899 1883
    } else if (to.IsSmi()) {
1900 1884
      HValue* val = instr->value();
1901 1885
      LOperand* value = UseRegister(val);
1902
      LInstruction* result =
1903
          DefineAsRegister(new(zone()) LInteger32ToSmi(value));
1904
      if (val->HasRange() && val->range()->IsInSmiRange()) {
1905
        return result;
1886
      LInstruction* result = NULL;
1887
      if (val->CheckFlag(HInstruction::kUint32)) {
1888
        result = DefineAsRegister(new(zone()) LUint32ToSmi(value));
1889
        if (val->HasRange() && val->range()->IsInSmiRange() &&
1890
            val->range()->upper() != kMaxInt) {
1891
          return result;
1892
        }
1893
      } else {
1894
        result = DefineAsRegister(new(zone()) LInteger32ToSmi(value));
1895
        if (val->HasRange() && val->range()->IsInSmiRange()) {
1896
          return result;
1897
        }
1906 1898
      }
1907 1899
      return AssignEnvironment(result);
1908 1900
    } else {
......
1934 1926
}
1935 1927

  
1936 1928

  
1937
LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) {
1938
  return new(zone()) LIsNumberAndBranch(
1939
      UseRegisterOrConstantAtStart(instr->value()));
1940
}
1941

  
1942

  
1943 1929
LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1944 1930
  LOperand* value = UseRegisterAtStart(instr->value());
1945 1931
  LCheckInstanceType* result = new(zone()) LCheckInstanceType(value);
......
2075 2061

  
2076 2062

  
2077 2063
LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2078
  if (instr->access().IsExternalMemory() && instr->access().offset() == 0) {
2064
  // Use the special mov rax, moffs64 encoding for external
2065
  // memory accesses with 64-bit word-sized values.
2066
  if (instr->access().IsExternalMemory() &&
2067
      instr->access().offset() == 0 &&
2068
      (instr->access().representation().IsSmi() ||
2069
       instr->access().representation().IsTagged() ||
2070
       instr->access().representation().IsHeapObject() ||
2071
       instr->access().representation().IsExternal())) {
2079 2072
    LOperand* obj = UseRegisterOrConstantAtStart(instr->object());
2080 2073
    return DefineFixed(new(zone()) LLoadNamedField(obj), rax);
2081 2074
  }
......
2098 2091
}
2099 2092

  
2100 2093

  
2094
LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2095
  return DefineAsRegister(new(zone()) LLoadRoot);
2096
}
2097

  
2098

  
2101 2099
LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
2102 2100
    HLoadExternalArrayPointer* instr) {
2103 2101
  LOperand* input = UseRegisterAtStart(instr->value());
......
2391 2389

  
2392 2390

  
2393 2391
LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2394
  argument_count_ -= instr->argument_count();
2395 2392
  return MarkAsCall(DefineFixed(new(zone()) LCallStub, rax), instr);
2396 2393
}
2397 2394

  
......
2513 2510
  if (env->entry()->arguments_pushed()) {
2514 2511
    int argument_count = env->arguments_environment()->parameter_count();
2515 2512
    pop = new(zone()) LDrop(argument_count);
2516
    argument_count_ -= argument_count;
2513
    ASSERT(instr->argument_delta() == -argument_count);
2517 2514
  }
2518 2515

  
2519 2516
  HEnvironment* outer = current_block_->last_environment()->

Also available in: Unified diff