Revision f230a1cf deps/v8/src/hydrogen.cc

View differences:

deps/v8/src/hydrogen.cc
30 30
#include <algorithm>
31 31

  
32 32
#include "v8.h"
33
#include "allocation-site-scopes.h"
33 34
#include "codegen.h"
34 35
#include "full-codegen.h"
35 36
#include "hashmap.h"
36 37
#include "hydrogen-bce.h"
37 38
#include "hydrogen-bch.h"
38 39
#include "hydrogen-canonicalize.h"
40
#include "hydrogen-check-elimination.h"
39 41
#include "hydrogen-dce.h"
40 42
#include "hydrogen-dehoist.h"
41
#include "hydrogen-deoptimizing-mark.h"
42 43
#include "hydrogen-environment-liveness.h"
43 44
#include "hydrogen-escape-analysis.h"
44 45
#include "hydrogen-infer-representation.h"
45 46
#include "hydrogen-infer-types.h"
47
#include "hydrogen-load-elimination.h"
46 48
#include "hydrogen-gvn.h"
47 49
#include "hydrogen-mark-deoptimize.h"
50
#include "hydrogen-mark-unreachable.h"
48 51
#include "hydrogen-minus-zero.h"
49 52
#include "hydrogen-osr.h"
50 53
#include "hydrogen-range-analysis.h"
......
94 97
      parent_loop_header_(NULL),
95 98
      inlined_entry_block_(NULL),
96 99
      is_inline_return_target_(false),
97
      is_deoptimizing_(false),
100
      is_reachable_(true),
98 101
      dominates_loop_successors_(false),
99 102
      is_osr_entry_(false) { }
100 103

  
......
104 107
}
105 108

  
106 109

  
110
void HBasicBlock::MarkUnreachable() {
111
  is_reachable_ = false;
112
}
113

  
114

  
107 115
void HBasicBlock::AttachLoopInformation() {
108 116
  ASSERT(!IsLoopHeader());
109 117
  loop_information_ = new(zone()) HLoopInformation(this, zone());
......
132 140
}
133 141

  
134 142

  
135
void HBasicBlock::AddInstruction(HInstruction* instr) {
143
void HBasicBlock::AddInstruction(HInstruction* instr, int position) {
136 144
  ASSERT(!IsStartBlock() || !IsFinished());
137 145
  ASSERT(!instr->IsLinked());
138 146
  ASSERT(!IsFinished());
139 147

  
148
  if (position != RelocInfo::kNoPosition) {
149
    instr->set_position(position);
150
  }
140 151
  if (first_ == NULL) {
141 152
    ASSERT(last_environment() != NULL);
142 153
    ASSERT(!last_environment()->ast_id().IsNone());
143 154
    HBlockEntry* entry = new(zone()) HBlockEntry();
144 155
    entry->InitializeAsFirst(this);
156
    if (position != RelocInfo::kNoPosition) {
157
      entry->set_position(position);
158
    } else {
159
      ASSERT(!FLAG_emit_opt_code_positions ||
160
             !graph()->info()->IsOptimizing());
161
    }
145 162
    first_ = last_ = entry;
146 163
  }
147 164
  instr->InsertAfter(last_);
......
192 209
}
193 210

  
194 211

  
195
void HBasicBlock::Finish(HControlInstruction* end) {
212
void HBasicBlock::Finish(HControlInstruction* end, int position) {
196 213
  ASSERT(!IsFinished());
197
  AddInstruction(end);
214
  AddInstruction(end, position);
198 215
  end_ = end;
199 216
  for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
200 217
    it.Current()->RegisterPredecessor(this);
......
203 220

  
204 221

  
205 222
void HBasicBlock::Goto(HBasicBlock* block,
223
                       int position,
206 224
                       FunctionState* state,
207 225
                       bool add_simulate) {
208 226
  bool drop_extra = state != NULL &&
209 227
      state->inlining_kind() == DROP_EXTRA_ON_RETURN;
210 228

  
211 229
  if (block->IsInlineReturnTarget()) {
212
    AddInstruction(new(zone()) HLeaveInlined());
230
    HEnvironment* env = last_environment();
231
    int argument_count = env->arguments_environment()->parameter_count();
232
    AddInstruction(new(zone())
233
                   HLeaveInlined(state->entry(), argument_count),
234
                   position);
213 235
    UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
214 236
  }
215 237

  
216
  if (add_simulate) AddNewSimulate(BailoutId::None());
238
  if (add_simulate) AddNewSimulate(BailoutId::None(), position);
217 239
  HGoto* instr = new(zone()) HGoto(block);
218
  Finish(instr);
240
  Finish(instr, position);
219 241
}
220 242

  
221 243

  
222 244
void HBasicBlock::AddLeaveInlined(HValue* return_value,
223
                                  FunctionState* state) {
245
                                  FunctionState* state,
246
                                  int position) {
224 247
  HBasicBlock* target = state->function_return();
225 248
  bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN;
226 249

  
227 250
  ASSERT(target->IsInlineReturnTarget());
228 251
  ASSERT(return_value != NULL);
229
  AddInstruction(new(zone()) HLeaveInlined());
252
  HEnvironment* env = last_environment();
253
  int argument_count = env->arguments_environment()->parameter_count();
254
  AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count),
255
                 position);
230 256
  UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
231 257
  last_environment()->Push(return_value);
232
  AddNewSimulate(BailoutId::None());
258
  AddNewSimulate(BailoutId::None(), position);
233 259
  HGoto* instr = new(zone()) HGoto(target);
234
  Finish(instr);
260
  Finish(instr, position);
235 261
}
236 262

  
237 263

  
......
622 648
    // Can't pass GetInvalidContext() to HConstant::New, because that will
623 649
    // recursively call GetConstant
624 650
    HConstant* constant = HConstant::New(zone(), NULL, value);
625
    constant->InsertAfter(GetConstantUndefined());
651
    constant->InsertAfter(entry_block()->first());
626 652
    pointer->set(constant);
653
    return constant;
627 654
  }
628
  return pointer->get();
655
  return ReinsertConstantIfNecessary(pointer->get());
656
}
657

  
658

  
659
HConstant* HGraph::ReinsertConstantIfNecessary(HConstant* constant) {
660
  if (!constant->IsLinked()) {
661
    // The constant was removed from the graph. Reinsert.
662
    constant->ClearFlag(HValue::kIsDead);
663
    constant->InsertAfter(entry_block()->first());
664
  }
665
  return constant;
629 666
}
630 667

  
631 668

  
......
648 685
HConstant* HGraph::GetConstant##Name() {                                       \
649 686
  if (!constant_##name##_.is_set()) {                                          \
650 687
    HConstant* constant = new(zone()) HConstant(                               \
651
        isolate()->factory()->name##_value(),                                  \
652
        UniqueValueId::name##_value(isolate()->heap()),                        \
688
        Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
653 689
        Representation::Tagged(),                                              \
654 690
        htype,                                                                 \
655 691
        false,                                                                 \
656 692
        true,                                                                  \
657 693
        false,                                                                 \
658 694
        boolean_value);                                                        \
659
    constant->InsertAfter(GetConstantUndefined());                             \
695
    constant->InsertAfter(entry_block()->first());                             \
660 696
    constant_##name##_.set(constant);                                          \
661 697
  }                                                                            \
662
  return constant_##name##_.get();                                             \
698
  return ReinsertConstantIfNecessary(constant_##name##_.get());                \
663 699
}
664 700

  
665 701

  
702
DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false)
666 703
DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true)
667 704
DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false)
668 705
DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
......
690 727
}
691 728

  
692 729

  
693
HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position)
730
HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder)
694 731
    : builder_(builder),
695
      position_(position),
696 732
      finished_(false),
697 733
      deopt_then_(false),
698 734
      deopt_else_(false),
......
715 751
    HGraphBuilder* builder,
716 752
    HIfContinuation* continuation)
717 753
    : builder_(builder),
718
      position_(RelocInfo::kNoPosition),
719 754
      finished_(false),
720 755
      deopt_then_(false),
721 756
      deopt_else_(false),
......
726 761
      captured_(false),
727 762
      needs_compare_(false),
728 763
      first_true_block_(NULL),
764
      last_true_block_(NULL),
729 765
      first_false_block_(NULL),
730 766
      split_edge_merge_block_(NULL),
731 767
      merge_block_(NULL) {
732 768
  continuation->Continue(&first_true_block_,
733
                         &first_false_block_,
734
                         &position_);
769
                         &first_false_block_);
735 770
}
736 771

  
737 772

  
738
void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
773
HControlInstruction* HGraphBuilder::IfBuilder::AddCompare(
774
    HControlInstruction* compare) {
739 775
  if (split_edge_merge_block_ != NULL) {
740 776
    HEnvironment* env = first_false_block_->last_environment();
741 777
    HBasicBlock* split_edge =
......
747 783
      compare->SetSuccessorAt(0, first_true_block_);
748 784
      compare->SetSuccessorAt(1, split_edge);
749 785
    }
750
    split_edge->GotoNoSimulate(split_edge_merge_block_);
786
    builder_->GotoNoSimulate(split_edge, split_edge_merge_block_);
751 787
  } else {
752 788
    compare->SetSuccessorAt(0, first_true_block_);
753 789
    compare->SetSuccessorAt(1, first_false_block_);
754 790
  }
755
  builder_->current_block()->Finish(compare);
791
  builder_->FinishCurrentBlock(compare);
756 792
  needs_compare_ = false;
793
  return compare;
757 794
}
758 795

  
759 796

  
760 797
void HGraphBuilder::IfBuilder::Or() {
798
  ASSERT(!needs_compare_);
761 799
  ASSERT(!did_and_);
762 800
  did_or_ = true;
763 801
  HEnvironment* env = first_false_block_->last_environment();
764 802
  if (split_edge_merge_block_ == NULL) {
765 803
    split_edge_merge_block_ =
766 804
        builder_->CreateBasicBlock(env->Copy());
767
    first_true_block_->GotoNoSimulate(split_edge_merge_block_);
805
    builder_->GotoNoSimulate(first_true_block_, split_edge_merge_block_);
768 806
    first_true_block_ = split_edge_merge_block_;
769 807
  }
770 808
  builder_->set_current_block(first_false_block_);
......
773 811

  
774 812

  
775 813
void HGraphBuilder::IfBuilder::And() {
814
  ASSERT(!needs_compare_);
776 815
  ASSERT(!did_or_);
777 816
  did_and_ = true;
778 817
  HEnvironment* env = first_false_block_->last_environment();
779 818
  if (split_edge_merge_block_ == NULL) {
780 819
    split_edge_merge_block_ = builder_->CreateBasicBlock(env->Copy());
781
    first_false_block_->GotoNoSimulate(split_edge_merge_block_);
820
    builder_->GotoNoSimulate(first_false_block_, split_edge_merge_block_);
782 821
    first_false_block_ = split_edge_merge_block_;
783 822
  }
784 823
  builder_->set_current_block(first_true_block_);
......
796 835
  HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL)
797 836
      ? builder_->current_block()
798 837
      : first_false_block_;
799
  continuation->Capture(true_block, false_block, position_);
838
  continuation->Capture(true_block, false_block);
839
  captured_ = true;
840
  End();
841
}
842

  
843

  
844
void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) {
845
  ASSERT(!finished_);
846
  ASSERT(!captured_);
847
  HBasicBlock* true_block = last_true_block_ == NULL
848
      ? first_true_block_
849
      : last_true_block_;
850
  HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL)
851
      ? builder_->current_block()
852
      : first_false_block_;
853
  if (true_block != NULL && !true_block->IsFinished()) {
854
    ASSERT(continuation->IsTrueReachable());
855
    builder_->GotoNoSimulate(true_block, continuation->true_branch());
856
  }
857
  if (false_block != NULL && !false_block->IsFinished()) {
858
    ASSERT(continuation->IsFalseReachable());
859
    builder_->GotoNoSimulate(false_block, continuation->false_branch());
860
  }
800 861
  captured_ = true;
801 862
  End();
802 863
}
......
814 875
    HConstant* constant_false = builder_->graph()->GetConstantFalse();
815 876
    ToBooleanStub::Types boolean_type = ToBooleanStub::Types();
816 877
    boolean_type.Add(ToBooleanStub::BOOLEAN);
817
    HBranch* branch =
818
        new(zone()) HBranch(constant_false, boolean_type, first_true_block_,
819
                            first_false_block_);
820
    builder_->current_block()->Finish(branch);
878
    HBranch* branch = builder()->New<HBranch>(
879
        constant_false, boolean_type, first_true_block_, first_false_block_);
880
    builder_->FinishCurrentBlock(branch);
821 881
  }
822 882
  builder_->set_current_block(first_true_block_);
823 883
}
......
845 905

  
846 906

  
847 907
void HGraphBuilder::IfBuilder::Return(HValue* value) {
848
  HBasicBlock* block = builder_->current_block();
849 908
  HValue* parameter_count = builder_->graph()->GetConstantMinus1();
850
  block->FinishExit(builder_->New<HReturn>(value, parameter_count));
851
  builder_->set_current_block(NULL);
909
  builder_->FinishExitCurrentBlock(
910
      builder_->New<HReturn>(value, parameter_count));
852 911
  if (did_else_) {
853 912
    first_false_block_ = NULL;
854 913
  } else {
......
878 937
      HBasicBlock* last_false_block = builder_->current_block();
879 938
      ASSERT(!last_false_block->IsFinished());
880 939
      if (deopt_then_) {
881
        last_false_block->GotoNoSimulate(merge_block_);
940
        builder_->GotoNoSimulate(last_false_block, merge_block_);
882 941
        builder_->PadEnvironmentForContinuation(last_true_block_,
883 942
                                                merge_block_);
884
        last_true_block_->GotoNoSimulate(merge_block_);
943
        builder_->GotoNoSimulate(last_true_block_, merge_block_);
885 944
      } else {
886
        last_true_block_->GotoNoSimulate(merge_block_);
945
        builder_->GotoNoSimulate(last_true_block_, merge_block_);
887 946
        if (deopt_else_) {
888 947
          builder_->PadEnvironmentForContinuation(last_false_block,
889 948
                                                  merge_block_);
890 949
        }
891
        last_false_block->GotoNoSimulate(merge_block_);
950
        builder_->GotoNoSimulate(last_false_block, merge_block_);
892 951
      }
893 952
      builder_->set_current_block(merge_block_);
894 953
    }
......
936 995
  phi_ = header_block_->AddNewPhi(env->values()->length());
937 996
  phi_->AddInput(initial);
938 997
  env->Push(initial);
939
  builder_->current_block()->GotoNoSimulate(header_block_);
998
  builder_->GotoNoSimulate(header_block_);
940 999

  
941 1000
  HEnvironment* body_env = env->Copy();
942 1001
  HEnvironment* exit_env = env->Copy();
......
948 1007

  
949 1008
  builder_->set_current_block(header_block_);
950 1009
  env->Pop();
951
  HCompareNumericAndBranch* compare =
952
      new(zone()) HCompareNumericAndBranch(phi_, terminating, token);
953
  compare->SetSuccessorAt(0, body_block_);
954
  compare->SetSuccessorAt(1, exit_block_);
955
  builder_->current_block()->Finish(compare);
1010
  builder_->FinishCurrentBlock(builder_->New<HCompareNumericAndBranch>(
1011
          phi_, terminating, token, body_block_, exit_block_));
956 1012

  
957 1013
  builder_->set_current_block(body_block_);
958 1014
  if (direction_ == kPreIncrement || direction_ == kPreDecrement) {
......
976 1032
    // Its the first time we saw a break.
977 1033
    HEnvironment* env = exit_block_->last_environment()->Copy();
978 1034
    exit_trampoline_block_ = builder_->CreateBasicBlock(env);
979
    exit_block_->GotoNoSimulate(exit_trampoline_block_);
1035
    builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_);
980 1036
  }
981 1037

  
982
  builder_->current_block()->GotoNoSimulate(exit_trampoline_block_);
1038
  builder_->GotoNoSimulate(exit_trampoline_block_);
983 1039
}
984 1040

  
985 1041

  
......
999 1055
  // Push the new increment value on the expression stack to merge into the phi.
1000 1056
  builder_->environment()->Push(increment_);
1001 1057
  HBasicBlock* last_block = builder_->current_block();
1002
  last_block->GotoNoSimulate(header_block_);
1058
  builder_->GotoNoSimulate(last_block, header_block_);
1003 1059
  header_block_->loop_information()->RegisterBackEdge(last_block);
1004 1060

  
1005 1061
  if (exit_trampoline_block_ != NULL) {
......
1017 1073
  CompilationPhase phase("H_Block building", info_);
1018 1074
  set_current_block(graph()->entry_block());
1019 1075
  if (!BuildGraph()) return NULL;
1020
  graph()->FinalizeUniqueValueIds();
1076
  graph()->FinalizeUniqueness();
1021 1077
  return graph_;
1022 1078
}
1023 1079

  
1024 1080

  
1025 1081
HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
1026 1082
  ASSERT(current_block() != NULL);
1027
  current_block()->AddInstruction(instr);
1083
  ASSERT(!FLAG_emit_opt_code_positions ||
1084
         position_ != RelocInfo::kNoPosition || !info_->IsOptimizing());
1085
  current_block()->AddInstruction(instr, position_);
1028 1086
  if (graph()->IsInsideNoSideEffectsScope()) {
1029 1087
    instr->SetFlag(HValue::kHasNoObservableSideEffects);
1030 1088
  }
......
1032 1090
}
1033 1091

  
1034 1092

  
1035
void HGraphBuilder::AddIncrementCounter(StatsCounter* counter,
1036
                                        HValue* context) {
1093
void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) {
1094
  ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() ||
1095
         position_ != RelocInfo::kNoPosition);
1096
  current_block()->Finish(last, position_);
1097
  if (last->IsReturn() || last->IsAbnormalExit()) {
1098
    set_current_block(NULL);
1099
  }
1100
}
1101

  
1102

  
1103
void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) {
1104
  ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() ||
1105
         position_ != RelocInfo::kNoPosition);
1106
  current_block()->FinishExit(instruction, position_);
1107
  if (instruction->IsReturn() || instruction->IsAbnormalExit()) {
1108
    set_current_block(NULL);
1109
  }
1110
}
1111

  
1112

  
1113
void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
1037 1114
  if (FLAG_native_code_counters && counter->Enabled()) {
1038 1115
    HValue* reference = Add<HConstant>(ExternalReference(counter));
1039 1116
    HValue* old_value = Add<HLoadNamedField>(reference,
......
1081 1158
  PadEnvironmentForContinuation(current_block(), continuation);
1082 1159
  Add<HDeoptimize>(reason, Deoptimizer::EAGER);
1083 1160
  if (graph()->IsInsideNoSideEffectsScope()) {
1084
    current_block()->GotoNoSimulate(continuation);
1161
    GotoNoSimulate(continuation);
1085 1162
  } else {
1086
    current_block()->Goto(continuation);
1163
    Goto(continuation);
1087 1164
  }
1088 1165
}
1089 1166

  
......
1128 1205
                                                 HValue* length,
1129 1206
                                                 HValue* key,
1130 1207
                                                 bool is_js_array) {
1131
  Zone* zone = this->zone();
1132 1208
  IfBuilder length_checker(this);
1133 1209

  
1134 1210
  Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ;
......
1144 1220
                                                Token::GTE);
1145 1221
  capacity_checker.Then();
1146 1222

  
1147
  HValue* context = environment()->context();
1148

  
1149 1223
  HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
1150 1224
  HValue* max_capacity = Add<HAdd>(current_capacity, max_gap);
1151 1225
  IfBuilder key_checker(this);
......
1166 1240
  capacity_checker.End();
1167 1241

  
1168 1242
  if (is_js_array) {
1169
    HValue* new_length = AddInstruction(
1170
        HAdd::New(zone, context, key, graph_->GetConstant1()));
1243
    HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1());
1171 1244
    new_length->ClearFlag(HValue::kCanOverflow);
1172 1245

  
1173 1246
    Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind),
......
1252 1325
}
1253 1326

  
1254 1327

  
1328
HValue* HGraphBuilder::BuildNumberToString(HValue* object,
1329
                                           Handle<Type> type) {
1330
  NoObservableSideEffectsScope scope(this);
1331

  
1332
  // Create a joinable continuation.
1333
  HIfContinuation found(graph()->CreateBasicBlock(),
1334
                        graph()->CreateBasicBlock());
1335

  
1336
  // Load the number string cache.
1337
  HValue* number_string_cache =
1338
      Add<HLoadRoot>(Heap::kNumberStringCacheRootIndex);
1339

  
1340
  // Make the hash mask from the length of the number string cache. It
1341
  // contains two elements (number and string) for each cache entry.
1342
  HValue* mask = AddLoadFixedArrayLength(number_string_cache);
1343
  mask->set_type(HType::Smi());
1344
  mask = Add<HSar>(mask, graph()->GetConstant1());
1345
  mask = Add<HSub>(mask, graph()->GetConstant1());
1346

  
1347
  // Check whether object is a smi.
1348
  IfBuilder if_objectissmi(this);
1349
  if_objectissmi.If<HIsSmiAndBranch>(object);
1350
  if_objectissmi.Then();
1351
  {
1352
    // Compute hash for smi similar to smi_get_hash().
1353
    HValue* hash = Add<HBitwise>(Token::BIT_AND, object, mask);
1354

  
1355
    // Load the key.
1356
    HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
1357
    HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
1358
                                  static_cast<HValue*>(NULL),
1359
                                  FAST_ELEMENTS, ALLOW_RETURN_HOLE);
1360

  
1361
    // Check if object == key.
1362
    IfBuilder if_objectiskey(this);
1363
    if_objectiskey.If<HCompareObjectEqAndBranch>(object, key);
1364
    if_objectiskey.Then();
1365
    {
1366
      // Make the key_index available.
1367
      Push(key_index);
1368
    }
1369
    if_objectiskey.JoinContinuation(&found);
1370
  }
1371
  if_objectissmi.Else();
1372
  {
1373
    if (type->Is(Type::Smi())) {
1374
      if_objectissmi.Deopt("Excepted smi");
1375
    } else {
1376
      // Check if the object is a heap number.
1377
      IfBuilder if_objectisnumber(this);
1378
      if_objectisnumber.If<HCompareMap>(
1379
          object, isolate()->factory()->heap_number_map());
1380
      if_objectisnumber.Then();
1381
      {
1382
        // Compute hash for heap number similar to double_get_hash().
1383
        HValue* low = Add<HLoadNamedField>(
1384
            object, HObjectAccess::ForHeapNumberValueLowestBits());
1385
        HValue* high = Add<HLoadNamedField>(
1386
            object, HObjectAccess::ForHeapNumberValueHighestBits());
1387
        HValue* hash = Add<HBitwise>(Token::BIT_XOR, low, high);
1388
        hash = Add<HBitwise>(Token::BIT_AND, hash, mask);
1389

  
1390
        // Load the key.
1391
        HValue* key_index = Add<HShl>(hash, graph()->GetConstant1());
1392
        HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
1393
                                      static_cast<HValue*>(NULL),
1394
                                      FAST_ELEMENTS, ALLOW_RETURN_HOLE);
1395

  
1396
        // Check if key is a heap number (the number string cache contains only
1397
        // SMIs and heap number, so it is sufficient to do a SMI check here).
1398
        IfBuilder if_keyisnotsmi(this);
1399
        if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key);
1400
        if_keyisnotsmi.Then();
1401
        {
1402
          // Check if values of key and object match.
1403
          IfBuilder if_keyeqobject(this);
1404
          if_keyeqobject.If<HCompareNumericAndBranch>(
1405
              Add<HLoadNamedField>(key, HObjectAccess::ForHeapNumberValue()),
1406
              Add<HLoadNamedField>(object, HObjectAccess::ForHeapNumberValue()),
1407
              Token::EQ);
1408
          if_keyeqobject.Then();
1409
          {
1410
            // Make the key_index available.
1411
            Push(key_index);
1412
          }
1413
          if_keyeqobject.JoinContinuation(&found);
1414
        }
1415
        if_keyisnotsmi.JoinContinuation(&found);
1416
      }
1417
      if_objectisnumber.Else();
1418
      {
1419
        if (type->Is(Type::Number())) {
1420
          if_objectisnumber.Deopt("Expected heap number");
1421
        }
1422
      }
1423
      if_objectisnumber.JoinContinuation(&found);
1424
    }
1425
  }
1426
  if_objectissmi.JoinContinuation(&found);
1427

  
1428
  // Check for cache hit.
1429
  IfBuilder if_found(this, &found);
1430
  if_found.Then();
1431
  {
1432
    // Count number to string operation in native code.
1433
    AddIncrementCounter(isolate()->counters()->number_to_string_native());
1434

  
1435
    // Load the value in case of cache hit.
1436
    HValue* key_index = Pop();
1437
    HValue* value_index = Add<HAdd>(key_index, graph()->GetConstant1());
1438
    Push(Add<HLoadKeyed>(number_string_cache, value_index,
1439
                         static_cast<HValue*>(NULL),
1440
                         FAST_ELEMENTS, ALLOW_RETURN_HOLE));
1441
  }
1442
  if_found.Else();
1443
  {
1444
    // Cache miss, fallback to runtime.
1445
    Add<HPushArgument>(object);
1446
    Push(Add<HCallRuntime>(
1447
            isolate()->factory()->empty_string(),
1448
            Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
1449
            1));
1450
  }
1451
  if_found.End();
1452

  
1453
  return Pop();
1454
}
1455

  
1456

  
1255 1457
HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1256 1458
    HValue* checked_object,
1257 1459
    HValue* key,
......
1303 1505
      HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
1304 1506
          key, graph()->GetConstant0(), Token::GTE);
1305 1507
      negative_checker.Then();
1306
      HInstruction* result = AddExternalArrayElementAccess(
1508
      HInstruction* result = AddElementAccess(
1307 1509
          external_elements, key, val, bounds_check, elements_kind, is_store);
1308 1510
      negative_checker.ElseDeopt("Negative key encountered");
1309 1511
      length_checker.End();
......
1313 1515
      checked_key = Add<HBoundsCheck>(key, length);
1314 1516
      HLoadExternalArrayPointer* external_elements =
1315 1517
          Add<HLoadExternalArrayPointer>(elements);
1316
      return AddExternalArrayElementAccess(
1518
      return AddElementAccess(
1317 1519
          external_elements, checked_key, val,
1318 1520
          checked_object, elements_kind, is_store);
1319 1521
    }
......
1346 1548
                                            elements_kind, length);
1347 1549
      } else {
1348 1550
        HCheckMaps* check_cow_map = Add<HCheckMaps>(
1349
            elements, isolate()->factory()->fixed_array_map(),
1350
            top_info());
1551
            elements, isolate()->factory()->fixed_array_map(), top_info());
1351 1552
        check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1352 1553
      }
1353 1554
    }
1354 1555
  }
1355
  return AddFastElementAccess(elements, checked_key, val, checked_object,
1356
                              elements_kind, is_store, load_mode, store_mode);
1556
  return AddElementAccess(elements, checked_key, val, checked_object,
1557
                          elements_kind, is_store, load_mode);
1357 1558
}
1358 1559

  
1359 1560

  
......
1443 1644
}
1444 1645

  
1445 1646

  
1446
HInstruction* HGraphBuilder::AddExternalArrayElementAccess(
1447
    HValue* external_elements,
1647
HInstruction* HGraphBuilder::AddElementAccess(
1648
    HValue* elements,
1448 1649
    HValue* checked_key,
1449 1650
    HValue* val,
1450 1651
    HValue* dependency,
1451 1652
    ElementsKind elements_kind,
1452
    bool is_store) {
1653
    bool is_store,
1654
    LoadKeyedHoleMode load_mode) {
1453 1655
  if (is_store) {
1454 1656
    ASSERT(val != NULL);
1455
    switch (elements_kind) {
1456
      case EXTERNAL_PIXEL_ELEMENTS: {
1457
        val = Add<HClampToUint8>(val);
1458
        break;
1459
      }
1460
      case EXTERNAL_BYTE_ELEMENTS:
1461
      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1462
      case EXTERNAL_SHORT_ELEMENTS:
1463
      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
1464
      case EXTERNAL_INT_ELEMENTS:
1465
      case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
1466
        break;
1467
      }
1468
      case EXTERNAL_FLOAT_ELEMENTS:
1469
      case EXTERNAL_DOUBLE_ELEMENTS:
1470
        break;
1471
      case FAST_SMI_ELEMENTS:
1472
      case FAST_ELEMENTS:
1473
      case FAST_DOUBLE_ELEMENTS:
1474
      case FAST_HOLEY_SMI_ELEMENTS:
1475
      case FAST_HOLEY_ELEMENTS:
1476
      case FAST_HOLEY_DOUBLE_ELEMENTS:
1477
      case DICTIONARY_ELEMENTS:
1478
      case NON_STRICT_ARGUMENTS_ELEMENTS:
1479
        UNREACHABLE();
1480
        break;
1657
    if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
1658
      val = Add<HClampToUint8>(val);
1481 1659
    }
1482
    return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind);
1483
  } else {
1484
    ASSERT(val == NULL);
1485
    HLoadKeyed* load = Add<HLoadKeyed>(external_elements,
1486
                                       checked_key,
1487
                                       dependency,
1488
                                       elements_kind);
1489
    if (FLAG_opt_safe_uint32_operations &&
1490
        elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
1491
      graph()->RecordUint32Instruction(load);
1492
    }
1493
    return load;
1660
    return Add<HStoreKeyed>(elements, checked_key, val, elements_kind);
1494 1661
  }
1495
}
1496

  
1497 1662

  
1498
HInstruction* HGraphBuilder::AddFastElementAccess(
1499
    HValue* elements,
1500
    HValue* checked_key,
1501
    HValue* val,
1502
    HValue* load_dependency,
1503
    ElementsKind elements_kind,
1504
    bool is_store,
1505
    LoadKeyedHoleMode load_mode,
1506
    KeyedAccessStoreMode store_mode) {
1507
  if (is_store) {
1508
    ASSERT(val != NULL);
1509
    switch (elements_kind) {
1510
      case FAST_SMI_ELEMENTS:
1511
      case FAST_HOLEY_SMI_ELEMENTS:
1512
      case FAST_ELEMENTS:
1513
      case FAST_HOLEY_ELEMENTS:
1514
      case FAST_DOUBLE_ELEMENTS:
1515
      case FAST_HOLEY_DOUBLE_ELEMENTS:
1516
        return Add<HStoreKeyed>(elements, checked_key, val, elements_kind);
1517
      default:
1518
        UNREACHABLE();
1519
        return NULL;
1520
    }
1663
  ASSERT(!is_store);
1664
  ASSERT(val == NULL);
1665
  HLoadKeyed* load = Add<HLoadKeyed>(
1666
      elements, checked_key, dependency, elements_kind, load_mode);
1667
  if (FLAG_opt_safe_uint32_operations &&
1668
      elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
1669
    graph()->RecordUint32Instruction(load);
1521 1670
  }
1522
  // It's an element load (!is_store).
1523
  return Add<HLoadKeyed>(
1524
      elements, checked_key, load_dependency, elements_kind, load_mode);
1671
  return load;
1525 1672
}
1526 1673

  
1527 1674

  
......
1771 1918
void HGraphBuilder::BuildCompareNil(
1772 1919
    HValue* value,
1773 1920
    Handle<Type> type,
1774
    int position,
1775 1921
    HIfContinuation* continuation) {
1776
  IfBuilder if_nil(this, position);
1922
  IfBuilder if_nil(this);
1777 1923
  bool some_case_handled = false;
1778 1924
  bool some_case_missing = false;
1779 1925

  
......
1824 1970
HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
1825 1971
                                                    int previous_object_size,
1826 1972
                                                    HValue* alloc_site) {
1827
  // TODO(mvstanton): ASSERT altered to CHECK to diagnose chromium bug 284577
1828
  CHECK(alloc_site != NULL);
1973
  ASSERT(alloc_site != NULL);
1829 1974
  HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>(
1830 1975
      previous_object, previous_object_size);
1831
  Handle<Map> alloc_memento_map(
1832
      isolate()->heap()->allocation_memento_map());
1976
  Handle<Map> alloc_memento_map =
1977
      isolate()->factory()->allocation_memento_map();
1833 1978
  AddStoreMapConstant(alloc_memento, alloc_memento_map);
1834 1979
  HObjectAccess access = HObjectAccess::ForAllocationMementoSite();
1835 1980
  Add<HStoreNamedField>(alloc_memento, access, alloc_site);
......
1886 2031
    // No need for a context lookup if the kind_ matches the initial
1887 2032
    // map, because we can just load the map in that case.
1888 2033
    HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1889
    return builder()->AddInstruction(
1890
        builder()->BuildLoadNamedField(constructor_function_, access));
2034
    return builder()->AddLoadNamedField(constructor_function_, access);
1891 2035
  }
1892 2036

  
1893 2037
  HInstruction* native_context = builder()->BuildGetNativeContext();
......
1907 2051
HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1908 2052
  // Find the map near the constructor function
1909 2053
  HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1910
  return builder()->AddInstruction(
1911
      builder()->BuildLoadNamedField(constructor_function_, access));
2054
  return builder()->AddLoadNamedField(constructor_function_, access);
1912 2055
}
1913 2056

  
1914 2057

  
......
1983 2126
  HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
1984 2127
      HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
1985 2128

  
2129
  // Folded array allocation should be aligned if it has fast double elements.
2130
  if (IsFastDoubleElementsKind(kind_)) {
2131
     new_object->MakeDoubleAligned();
2132
  }
2133

  
1986 2134
  // Fill in the fields: map, properties, length
1987 2135
  HValue* map;
1988 2136
  if (allocation_site_payload_ == NULL) {
......
2042 2190
  // to know it's the initial state.
2043 2191
  function_state_= &initial_function_state_;
2044 2192
  InitializeAstVisitor(info->isolate());
2193
  if (FLAG_emit_opt_code_positions) {
2194
    SetSourcePosition(info->shared_info()->start_position());
2195
  }
2045 2196
}
2046 2197

  
2047 2198

  
......
2054 2205
    return first;
2055 2206
  } else {
2056 2207
    HBasicBlock* join_block = graph()->CreateBasicBlock();
2057
    first->Goto(join_block);
2058
    second->Goto(join_block);
2208
    Goto(first, join_block);
2209
    Goto(second, join_block);
2059 2210
    join_block->SetJoinId(join_id);
2060 2211
    return join_block;
2061 2212
  }
......
2066 2217
                                                  HBasicBlock* exit_block,
2067 2218
                                                  HBasicBlock* continue_block) {
2068 2219
  if (continue_block != NULL) {
2069
    if (exit_block != NULL) exit_block->Goto(continue_block);
2220
    if (exit_block != NULL) Goto(exit_block, continue_block);
2070 2221
    continue_block->SetJoinId(statement->ContinueId());
2071 2222
    return continue_block;
2072 2223
  }
......
2079 2230
                                                HBasicBlock* body_exit,
2080 2231
                                                HBasicBlock* loop_successor,
2081 2232
                                                HBasicBlock* break_block) {
2082
  if (body_exit != NULL) body_exit->Goto(loop_entry);
2233
  if (body_exit != NULL) Goto(body_exit, loop_entry);
2083 2234
  loop_entry->PostProcessLoopHeader(statement);
2084 2235
  if (break_block != NULL) {
2085
    if (loop_successor != NULL) loop_successor->Goto(break_block);
2236
    if (loop_successor != NULL) Goto(loop_successor, break_block);
2086 2237
    break_block->SetJoinId(statement->ExitId());
2087 2238
    return break_block;
2088 2239
  }
......
2090 2241
}
2091 2242

  
2092 2243

  
2093
void HBasicBlock::FinishExit(HControlInstruction* instruction) {
2094
  Finish(instruction);
2244
// Build a new loop header block and set it as the current block.
2245
HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry() {
2246
  HBasicBlock* loop_entry = CreateLoopHeaderBlock();
2247
  Goto(loop_entry);
2248
  set_current_block(loop_entry);
2249
  return loop_entry;
2250
}
2251

  
2252

  
2253
HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry(
2254
    IterationStatement* statement) {
2255
  HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement)
2256
      ? osr()->BuildOsrLoopEntry(statement)
2257
      : BuildLoopEntry();
2258
  return loop_entry;
2259
}
2260

  
2261

  
2262
void HBasicBlock::FinishExit(HControlInstruction* instruction, int position) {
2263
  Finish(instruction, position);
2095 2264
  ClearEnvironment();
2096 2265
}
2097 2266

  
......
2109 2278
      zone_(info->zone()),
2110 2279
      is_recursive_(false),
2111 2280
      use_optimistic_licm_(false),
2112
      has_soft_deoptimize_(false),
2113 2281
      depends_on_empty_array_proto_elements_(false),
2114 2282
      type_change_checksum_(0),
2115 2283
      maximum_environment_size_(0),
......
2137 2305
}
2138 2306

  
2139 2307

  
2140
void HGraph::FinalizeUniqueValueIds() {
2308
void HGraph::FinalizeUniqueness() {
2141 2309
  DisallowHeapAllocation no_gc;
2142 2310
  ASSERT(!isolate()->optimizing_compiler_thread()->IsOptimizerThread());
2143 2311
  for (int i = 0; i < blocks()->length(); ++i) {
2144 2312
    for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
2145
      it.Current()->FinalizeUniqueValueId();
2313
      it.Current()->FinalizeUniqueness();
2146 2314
    }
2147 2315
  }
2148 2316
}
......
2640 2808
  HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
2641 2809
  instr->SetSuccessorAt(0, empty_true);
2642 2810
  instr->SetSuccessorAt(1, empty_false);
2643
  owner()->current_block()->Finish(instr);
2811
  owner()->FinishCurrentBlock(instr);
2644 2812
  HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id);
2645 2813
  owner()->set_current_block(join);
2646 2814
}
......
2650 2818
                                       BailoutId ast_id) {
2651 2819
  HBasicBlock* true_branch = NULL;
2652 2820
  HBasicBlock* false_branch = NULL;
2653
  continuation->Continue(&true_branch, &false_branch, NULL);
2821
  continuation->Continue(&true_branch, &false_branch);
2654 2822
  if (!continuation->IsTrueReachable()) {
2655 2823
    owner()->set_current_block(false_branch);
2656 2824
  } else if (!continuation->IsFalseReachable()) {
......
2684 2852
  HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock();
2685 2853
  instr->SetSuccessorAt(0, materialize_true);
2686 2854
  instr->SetSuccessorAt(1, materialize_false);
2687
  owner()->current_block()->Finish(instr);
2855
  owner()->FinishCurrentBlock(instr);
2688 2856
  owner()->set_current_block(materialize_true);
2689 2857
  owner()->Push(owner()->graph()->GetConstantTrue());
2690 2858
  owner()->set_current_block(materialize_false);
......
2699 2867
                                      BailoutId ast_id) {
2700 2868
  HBasicBlock* materialize_true = NULL;
2701 2869
  HBasicBlock* materialize_false = NULL;
2702
  continuation->Continue(&materialize_true, &materialize_false, NULL);
2870
  continuation->Continue(&materialize_true, &materialize_false);
2703 2871
  if (continuation->IsTrueReachable()) {
2704 2872
    owner()->set_current_block(materialize_true);
2705 2873
    owner()->Push(owner()->graph()->GetConstantTrue());
......
2739 2907
  HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
2740 2908
  instr->SetSuccessorAt(0, empty_true);
2741 2909
  instr->SetSuccessorAt(1, empty_false);
2742
  owner()->current_block()->Finish(instr);
2743
  empty_true->Goto(if_true(), owner()->function_state());
2744
  empty_false->Goto(if_false(), owner()->function_state());
2910
  owner()->FinishCurrentBlock(instr);
2911
  owner()->Goto(empty_true, if_true(), owner()->function_state());
2912
  owner()->Goto(empty_false, if_false(), owner()->function_state());
2745 2913
  owner()->set_current_block(NULL);
2746 2914
}
2747 2915

  
......
2750 2918
                                     BailoutId ast_id) {
2751 2919
  HBasicBlock* true_branch = NULL;
2752 2920
  HBasicBlock* false_branch = NULL;
2753
  continuation->Continue(&true_branch, &false_branch, NULL);
2921
  continuation->Continue(&true_branch, &false_branch);
2754 2922
  if (continuation->IsTrueReachable()) {
2755
    true_branch->Goto(if_true(), owner()->function_state());
2923
    owner()->Goto(true_branch, if_true(), owner()->function_state());
2756 2924
  }
2757 2925
  if (continuation->IsFalseReachable()) {
2758
    false_branch->Goto(if_false(), owner()->function_state());
2926
    owner()->Goto(false_branch, if_false(), owner()->function_state());
2759 2927
  }
2760 2928
  owner()->set_current_block(NULL);
2761 2929
}
......
2773 2941
  HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
2774 2942
  HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
2775 2943
  ToBooleanStub::Types expected(condition()->to_boolean_types());
2776
  HBranch* test = new(zone()) HBranch(value, expected, empty_true, empty_false);
2777
  builder->current_block()->Finish(test);
2944
  builder->FinishCurrentBlock(builder->New<HBranch>(
2945
          value, expected, empty_true, empty_false));
2778 2946

  
2779
  empty_true->Goto(if_true(), builder->function_state());
2780
  empty_false->Goto(if_false(), builder->function_state());
2947
  owner()->Goto(empty_true, if_true(), builder->function_state());
2948
  owner()->Goto(empty_false , if_false(), builder->function_state());
2781 2949
  builder->set_current_block(NULL);
2782 2950
}
2783 2951

  
......
2894 3062
  // not replayed by the Lithium translation.
2895 3063
  HEnvironment* initial_env = environment()->CopyWithoutHistory();
2896 3064
  HBasicBlock* body_entry = CreateBasicBlock(initial_env);
2897
  current_block()->Goto(body_entry);
3065
  Goto(body_entry);
2898 3066
  body_entry->SetJoinId(BailoutId::FunctionEntry());
2899 3067
  set_current_block(body_entry);
2900 3068

  
......
2906 3074
  VisitDeclarations(scope->declarations());
2907 3075
  Add<HSimulate>(BailoutId::Declarations());
2908 3076

  
2909
  HValue* context = environment()->context();
2910
  Add<HStackCheck>(context, HStackCheck::kFunctionEntry);
3077
  Add<HStackCheck>(HStackCheck::kFunctionEntry);
2911 3078

  
2912 3079
  VisitStatements(current_info()->function()->body());
2913 3080
  if (HasStackOverflow()) return false;
......
2932 3099
  type_info->set_inlined_type_change_checksum(composite_checksum);
2933 3100

  
2934 3101
  // Perform any necessary OSR-specific cleanups or changes to the graph.
2935
  osr_->FinishGraph();
3102
  osr()->FinishGraph();
2936 3103

  
2937 3104
  return true;
2938 3105
}
......
2957 3124
    Run<HEnvironmentLivenessAnalysisPhase>();
2958 3125
  }
2959 3126

  
2960
  Run<HPropagateDeoptimizingMarkPhase>();
2961 3127
  if (!CheckConstPhiUses()) {
2962 3128
    *bailout_reason = kUnsupportedPhiUseOfConstVariable;
2963 3129
    return false;
......
2968 3134
    return false;
2969 3135
  }
2970 3136

  
2971
  // Remove dead code and phis
2972
  if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
3137
  // Find and mark unreachable code to simplify optimizations, especially gvn,
3138
  // where unreachable code could unnecessarily defeat LICM.
3139
  Run<HMarkUnreachableBlocksPhase>();
2973 3140

  
3141
  if (FLAG_check_elimination) Run<HCheckEliminationPhase>();
3142
  if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
2974 3143
  if (FLAG_use_escape_analysis) Run<HEscapeAnalysisPhase>();
2975 3144

  
3145
  if (FLAG_load_elimination) Run<HLoadEliminationPhase>();
3146

  
2976 3147
  CollectPhis();
2977 3148

  
2978 3149
  if (has_osr()) osr()->FinishOsrValues();
......
3006 3177
  // Eliminate redundant stack checks on backwards branches.
3007 3178
  Run<HStackCheckEliminationPhase>();
3008 3179

  
3009
  if (FLAG_array_bounds_checks_elimination) {
3010
    Run<HBoundsCheckEliminationPhase>();
3011
  }
3012
  if (FLAG_array_bounds_checks_hoisting) {
3013
    Run<HBoundsCheckHoistingPhase>();
3014
  }
3180
  if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>();
3181
  if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>();
3015 3182
  if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
3016 3183
  if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
3017 3184

  
3018 3185
  RestoreActualValues();
3019 3186

  
3187
  // Find unreachable code a second time, GVN and other optimizations may have
3188
  // made blocks unreachable that were previously reachable.
3189
  Run<HMarkUnreachableBlocksPhase>();
3190

  
3020 3191
  return true;
3021 3192
}
3022 3193

  
......
3049 3220
}
3050 3221

  
3051 3222

  
3052
void HGraphBuilder::PushAndAdd(HInstruction* instr) {
3053
  Push(instr);
3054
  AddInstruction(instr);
3055
}
3056

  
3057

  
3058 3223
template <class Instruction>
3059 3224
HInstruction* HOptimizedGraphBuilder::PreProcessCall(Instruction* call) {
3060 3225
  int count = call->argument_count();
......
3075 3240
  HInstruction* context = Add<HContext>();
3076 3241
  environment()->BindContext(context);
3077 3242

  
3078
  HConstant* undefined_constant = HConstant::cast(Add<HConstant>(
3079
      isolate()->factory()->undefined_value()));
3080
  graph()->set_undefined_constant(undefined_constant);
3081

  
3082 3243
  // Create an arguments object containing the initial parameters.  Set the
3083 3244
  // initial values of parameters including "this" having parameter index 0.
3084 3245
  ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count());
......
3092 3253
  AddInstruction(arguments_object);
3093 3254
  graph()->SetArgumentsObject(arguments_object);
3094 3255

  
3256
  HConstant* undefined_constant = graph()->GetConstantUndefined();
3095 3257
  // Initialize specials and locals to undefined.
3096 3258
  for (int i = environment()->parameter_count() + 1;
3097 3259
       i < environment()->length();
......
3134 3296
  }
3135 3297
  HBasicBlock* break_block = break_info.break_block();
3136 3298
  if (break_block != NULL) {
3137
    if (current_block() != NULL) current_block()->Goto(break_block);
3299
    if (current_block() != NULL) Goto(break_block);
3138 3300
    break_block->SetJoinId(stmt->ExitId());
3139 3301
    set_current_block(break_block);
3140 3302
  }
......
3244 3406
  HBasicBlock* continue_block = break_scope()->Get(
3245 3407
      stmt->target(), BreakAndContinueScope::CONTINUE, &drop_extra);
3246 3408
  Drop(drop_extra);
3247
  current_block()->Goto(continue_block);
3409
  Goto(continue_block);
3248 3410
  set_current_block(NULL);
3249 3411
}
3250 3412

  
......
3257 3419
  HBasicBlock* break_block = break_scope()->Get(
3258 3420
      stmt->target(), BreakAndContinueScope::BREAK, &drop_extra);
3259 3421
  Drop(drop_extra);
3260
  current_block()->Goto(break_block);
3422
  Goto(break_block);
3261 3423
  set_current_block(NULL);
3262 3424
}
3263 3425

  
......
3280 3442
    if (context->IsTest()) {
3281 3443
      TestContext* test = TestContext::cast(context);
3282 3444
      CHECK_ALIVE(VisitForEffect(stmt->expression()));
3283
      current_block()->Goto(test->if_true(), state);
3445
      Goto(test->if_true(), state);
3284 3446
    } else if (context->IsEffect()) {
3285 3447
      CHECK_ALIVE(VisitForEffect(stmt->expression()));
3286
      current_block()->Goto(function_return(), state);
3448
      Goto(function_return(), state);
3287 3449
    } else {
3288 3450
      ASSERT(context->IsValue());
3289 3451
      CHECK_ALIVE(VisitForValue(stmt->expression()));
3290 3452
      HValue* return_value = Pop();
3291 3453
      HValue* receiver = environment()->arguments_environment()->Lookup(0);
3292 3454
      HHasInstanceTypeAndBranch* typecheck =
3293
          new(zone()) HHasInstanceTypeAndBranch(return_value,
3294
                                                FIRST_SPEC_OBJECT_TYPE,
3295
                                                LAST_SPEC_OBJECT_TYPE);
3455
          New<HHasInstanceTypeAndBranch>(return_value,
3456
                                         FIRST_SPEC_OBJECT_TYPE,
3457
                                         LAST_SPEC_OBJECT_TYPE);
3296 3458
      HBasicBlock* if_spec_object = graph()->CreateBasicBlock();
3297 3459
      HBasicBlock* not_spec_object = graph()->CreateBasicBlock();
3298 3460
      typecheck->SetSuccessorAt(0, if_spec_object);
3299 3461
      typecheck->SetSuccessorAt(1, not_spec_object);
3300
      current_block()->Finish(typecheck);
3301
      if_spec_object->AddLeaveInlined(return_value, state);
3302
      not_spec_object->AddLeaveInlined(receiver, state);
3462
      FinishCurrentBlock(typecheck);
3463
      AddLeaveInlined(if_spec_object, return_value, state);
3464
      AddLeaveInlined(not_spec_object, receiver, state);
3303 3465
    }
3304 3466
  } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
3305 3467
    // Return from an inlined setter call. The returned value is never used, the
......
3309 3471
      HValue* rhs = environment()->arguments_environment()->Lookup(1);
3310 3472
      context->ReturnValue(rhs);
3311 3473
    } else if (context->IsEffect()) {
3312
      current_block()->Goto(function_return(), state);
3474
      Goto(function_return(), state);
3313 3475
    } else {
3314 3476
      ASSERT(context->IsValue());
3315 3477
      HValue* rhs = environment()->arguments_environment()->Lookup(1);
3316
      current_block()->AddLeaveInlined(rhs, state);
3478
      AddLeaveInlined(rhs, state);
3317 3479
    }
3318 3480
  } else {
3319 3481
    // Return from a normal inlined function. Visit the subexpression in the
......
3323 3485
      VisitForControl(stmt->expression(), test->if_true(), test->if_false());
3324 3486
    } else if (context->IsEffect()) {
3325 3487
      CHECK_ALIVE(VisitForEffect(stmt->expression()));
3326
      current_block()->Goto(function_return(), state);
3488
      Goto(function_return(), state);
3327 3489
    } else {
3328 3490
      ASSERT(context->IsValue());
3329 3491
      CHECK_ALIVE(VisitForValue(stmt->expression()));
3330
      current_block()->AddLeaveInlined(Pop(), state);
3492
      AddLeaveInlined(Pop(), state);
3331 3493
    }
3332 3494
  }
3333 3495
  set_current_block(NULL);
......
3361 3523
    return Bailout(kSwitchStatementMixedOrNonLiteralSwitchLabels);
3362 3524
  }
3363 3525

  
3364
  HValue* context = environment()->context();
3365

  
3366 3526
  CHECK_ALIVE(VisitForValue(stmt->tag()));
3367 3527
  Add<HSimulate>(stmt->EntryId());
3368 3528
  HValue* tag_value = Pop();
......
3373 3533

  
3374 3534
  // Test switch's tag value if all clauses are string literals
3375 3535
  if (stmt->switch_type() == SwitchStatement::STRING_SWITCH) {
3376
    string_check = new(zone()) HIsStringAndBranch(tag_value);
3377 3536
    first_test_block = graph()->CreateBasicBlock();
3378 3537
    not_string_block = graph()->CreateBasicBlock();
3379

  
3380
    string_check->SetSuccessorAt(0, first_test_block);
3381
    string_check->SetSuccessorAt(1, not_string_block);
3382
    current_block()->Finish(string_check);
3538
    string_check = New<HIsStringAndBranch>(
3539
        tag_value, first_test_block, not_string_block);
3540
    FinishCurrentBlock(string_check);
3383 3541

  
3384 3542
    set_current_block(first_test_block);
3385 3543
  }
......
3408 3566
      }
3409 3567

  
3410 3568
      HCompareNumericAndBranch* compare_ =
3411
          new(zone()) HCompareNumericAndBranch(tag_value,
3412
                                               label_value,
3413
                                               Token::EQ_STRICT);
3569
          New<HCompareNumericAndBranch>(tag_value,
3570
                                        label_value,
3571
                                        Token::EQ_STRICT);
3414 3572
      compare_->set_observed_input_representation(
3415 3573
          Representation::Smi(), Representation::Smi());
3416 3574
      compare = compare_;
3417 3575
    } else {
3418
      compare = new(zone()) HStringCompareAndBranch(context, tag_value,
3419
                                                    label_value,
3420
                                                    Token::EQ_STRICT);
3576
      compare = New<HStringCompareAndBranch>(tag_value,
3577
                                             label_value,
3578
                                             Token::EQ_STRICT);
3421 3579
    }
3422 3580

  
3423 3581
    compare->SetSuccessorAt(0, body_block);
3424 3582
    compare->SetSuccessorAt(1, next_test_block);
3425
    current_block()->Finish(compare);
3583
    FinishCurrentBlock(compare);
3426 3584

  
3427 3585
    set_current_block(next_test_block);
3428 3586
  }
......
3455 3613
          last_block = NULL;  // Cleared to indicate we've handled it.
3456 3614
        }
3457 3615
      } else {
3616
        // If the current test block is deoptimizing due to an unhandled clause
3617
        // of the switch, the test instruction is in the next block since the
3618
        // deopt must end the current block.
3619
        if (curr_test_block->IsDeoptimizing()) {
3620
          ASSERT(curr_test_block->end()->SecondSuccessor() == NULL);
3621
          curr_test_block = curr_test_block->end()->FirstSuccessor();
3622
        }
3458 3623
        normal_block = curr_test_block->end()->FirstSuccessor();
3459 3624
        curr_test_block = curr_test_block->end()->SecondSuccessor();
3460 3625
      }
......
3496 3661
                                 last_block,
3497 3662
                                 stmt->ExitId()));
3498 3663
  } else {
3499
    if (fall_through_block != NULL) fall_through_block->Goto(break_block);
3500
    if (last_block != NULL) last_block->Goto(break_block);
3664
    if (fall_through_block != NULL) Goto(fall_through_block, break_block);
3665
    if (last_block != NULL) Goto(last_block, break_block);
3501 3666
    break_block->SetJoinId(stmt->ExitId());
3502 3667
    set_current_block(break_block);
3503 3668
  }
......
3509 3674
                                           BreakAndContinueInfo* break_info) {
3510 3675
  BreakAndContinueScope push(break_info, this);
3511 3676
  Add<HSimulate>(stmt->StackCheckId());
3512
  HValue* context = environment()->context();
3513
  HStackCheck* stack_check = HStackCheck::cast(Add<HStackCheck>(
3514
      context, HStackCheck::kBackwardsBranch));
3677
  HStackCheck* stack_check =
3678
      HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch));
3515 3679
  ASSERT(loop_entry->IsLoopHeader());
3516 3680
  loop_entry->loop_information()->set_stack_check(stack_check);
3517 3681
  CHECK_BAILOUT(Visit(stmt->body()));
......
3523 3687
  ASSERT(current_block() != NULL);
3524 3688
  ASSERT(current_block()->HasPredecessor());
3525 3689
  ASSERT(current_block() != NULL);
3526
  HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
3690
  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3527 3691

  
3528 3692
  BreakAndContinueInfo break_info(stmt);
3529 3693
  CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
......
3562 3726
  ASSERT(current_block() != NULL);
3563 3727
  ASSERT(current_block()->HasPredecessor());
3564 3728
  ASSERT(current_block() != NULL);
3565
  HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
3729
  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3566 3730

  
3567 3731
  // If the condition is constant true, do not generate a branch.
3568 3732
  HBasicBlock* loop_successor = NULL;
......
3604 3768
    CHECK_ALIVE(Visit(stmt->init()));
3605 3769
  }
3606 3770
  ASSERT(current_block() != NULL);
3607
  HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
3771
  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3608 3772

  
3609 3773
  HBasicBlock* loop_successor = NULL;
3610 3774
  if (stmt->cond() != NULL) {
......
3687 3851
  HForInCacheArray::cast(array)->set_index_cache(
3688 3852
      HForInCacheArray::cast(index_cache));
3689 3853

  
3690
  HBasicBlock* loop_entry = osr_->BuildPossibleOsrLoopEntry(stmt);
3854
  HBasicBlock* loop_entry = BuildLoopEntry(stmt);
3691 3855

  
3692 3856
  HValue* index = environment()->ExpressionStackAt(0);
3693 3857
  HValue* limit = environment()->ExpressionStackAt(1);
3694 3858

  
3695 3859
  // Check that we still have more keys.
3696 3860
  HCompareNumericAndBranch* compare_index =
3697
      new(zone()) HCompareNumericAndBranch(index, limit, Token::LT);
3861
      New<HCompareNumericAndBranch>(index, limit, Token::LT);
3698 3862
  compare_index->set_observed_input_representation(
3699 3863
      Representation::Smi(), Representation::Smi());
3700 3864

  
......
3703 3867

  
3704 3868
  compare_index->SetSuccessorAt(0, loop_body);
3705 3869
  compare_index->SetSuccessorAt(1, loop_successor);
3706
  current_block()->Finish(compare_index);
3870
  FinishCurrentBlock(compare_index);
3707 3871

  
3708 3872
  set_current_block(loop_successor);
3709 3873
  Drop(5);
......
3733 3897
    set_current_block(body_exit);
3734 3898

  
3735 3899
    HValue* current_index = Pop();
3736
    HInstruction* new_index = New<HAdd>(current_index,
3737
                                        graph()->GetConstant1());
3738
    PushAndAdd(new_index);
3900
    Push(Add<HAdd>(current_index, graph()->GetConstant1()));
3739 3901
    body_exit = current_block();
3740 3902
  }
3741 3903

  
......
3782 3944
}
3783 3945

  
3784 3946

  
3947
void HOptimizedGraphBuilder::VisitCaseClause(CaseClause* clause) {
3948
  UNREACHABLE();
3949
}
3950

  
3951

  
3785 3952
static Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
3786 3953
    Code* unoptimized_code, FunctionLiteral* expr) {
3787 3954
  int start_position = expr->start_position();
......
3812 3979
  }
3813 3980
  // We also have a stack overflow if the recursive compilation did.
3814 3981
  if (HasStackOverflow()) return;
3815
  HValue* context = environment()->context();
3816 3982
  HFunctionLiteral* instr =
3817
      new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure());
3983
      New<HFunctionLiteral>(shared_info, expr->pretenure());
3818 3984
  return ast_context()->ReturnInstruction(instr, expr->id());
3819 3985
}
3820 3986

  
3821 3987

  
3822
void HOptimizedGraphBuilder::VisitSharedFunctionInfoLiteral(
3823
    SharedFunctionInfoLiteral* expr) {
3988
void HOptimizedGraphBuilder::VisitNativeFunctionLiteral(
3989
    NativeFunctionLiteral* expr) {
3824 3990
  ASSERT(!HasStackOverflow());
3825 3991
  ASSERT(current_block() != NULL);
3826 3992
  ASSERT(current_block()->HasPredecessor());
3827
  return Bailout(kSharedFunctionInfoLiteral);
3993
  return Bailout(kNativeFunctionLiteral);
3828 3994
}
3829 3995

  
3830 3996

  
......
3938 4104
          return ast_context()->ReturnInstruction(constant, expr->id());
3939 4105
        } else {
3940 4106
          HLoadGlobalCell* instr =
3941
              new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails());
4107
              New<HLoadGlobalCell>(cell, lookup.GetPropertyDetails());
3942 4108
          return ast_context()->ReturnInstruction(instr, expr->id());
3943 4109
        }
3944 4110
      } else {
3945
        HValue* context = environment()->context();
3946
        HGlobalObject* global_object = new(zone()) HGlobalObject(context);
3947
        AddInstruction(global_object);
4111
        HGlobalObject* global_object = Add<HGlobalObject>();
3948 4112
        HLoadGlobalGeneric* instr =
3949
            new(zone()) HLoadGlobalGeneric(context,
3950
                                           global_object,
3951
                                           variable->name(),
3952
                                           ast_context()->is_for_typeof());
3953
        instr->set_position(expr->position());
4113
            New<HLoadGlobalGeneric>(global_object,
4114
                                    variable->name(),
4115
                                    ast_context()->is_for_typeof());
3954 4116
        return ast_context()->ReturnInstruction(instr, expr->id());
3955 4117
      }
3956 4118
    }
......
3993 4155
  ASSERT(current_block()->HasPredecessor());
3994 4156
  Handle<JSFunction> closure = function_state()->compilation_info()->closure();
3995 4157
  Handle<FixedArray> literals(closure->literals());
3996
  HValue* context = environment()->context();
3997

  
3998
  HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context,
3999
                                                     literals,
4000
                                                     expr->pattern(),
4001
                                                     expr->flags(),
4002
                                                     expr->literal_index());
4158
  HRegExpLiteral* instr = New<HRegExpLiteral>(literals,
4159
                                              expr->pattern(),
4160
                                              expr->flags(),
4161
                                              expr->literal_index());
4003 4162
  return ast_context()->ReturnInstruction(instr, expr->id());
4004 4163
}
4005 4164

  
......
4064 4223
}
4065 4224

  
4066 4225

  
4067
static bool LookupGetter(Handle<Map> map,
4068
                         Handle<String> name,
4069
                         Handle<JSFunction>* getter,
4070
                         Handle<JSObject>* holder) {
4071
  Handle<AccessorPair> accessors;
4072
  if (LookupAccessorPair(map, name, &accessors, holder) &&
4073
      accessors->getter()->IsJSFunction()) {
4074
    *getter = Handle<JSFunction>(JSFunction::cast(accessors->getter()));
4075
    return true;
4076
  }
4077
  return false;
4078
}
4079

  
4080

  
4081 4226
static bool LookupSetter(Handle<Map> map,
4082 4227
                         Handle<String> name,
4083 4228
                         Handle<JSFunction>* setter,
......
4085 4230
  Handle<AccessorPair> accessors;
4086 4231
  if (LookupAccessorPair(map, name, &accessors, holder) &&
4087 4232
      accessors->setter()->IsJSFunction()) {
4088
    *setter = Handle<JSFunction>(JSFunction::cast(accessors->setter()));
4233
    Handle<JSFunction> func(JSFunction::cast(accessors->setter()));
4234
    CallOptimization call_optimization(func);
4235
    // TODO(dcarney): temporary hack unless crankshaft can handle api calls.
4236
    if (call_optimization.is_simple_api_call()) return false;
4237
    *setter = func;
4089 4238
    return true;
4090 4239
  }
4091 4240
  return false;
......
4100 4249
                          int* max_properties) {
4101 4250
  if (boilerplate->map()->is_deprecated()) {
4102 4251
    Handle<Object> result = JSObject::TryMigrateInstance(boilerplate);
4103
    if (result->IsSmi()) return false;
4252
    if (result.is_null()) return false;
4104 4253
  }
4105 4254

  
4106 4255
  ASSERT(max_depth >= 0 && *max_properties >= 0);
......
4166 4315

  
4167 4316
  // Check whether to use fast or slow deep-copying for boilerplate.
4168 4317
  int max_properties = kMaxFastLiteralProperties;
4169
  Handle<Object> boilerplate(closure->literals()->get(
4170
      expr->literal_index()), isolate());
4171
  if (boilerplate->IsJSObject() &&
4172
      IsFastLiteral(Handle<JSObject>::cast(boilerplate),
4173
                    kMaxFastLiteralDepth,
4174
                    &max_properties)) {
4175
    Handle<JSObject> boilerplate_object =
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff