Revision f230a1cf deps/v8/src/hydrogen.h

View differences:

deps/v8/src/hydrogen.h
30 30

  
31 31
#include "v8.h"
32 32

  
33
#include "accessors.h"
33 34
#include "allocation.h"
34 35
#include "ast.h"
35 36
#include "compiler.h"
......
109 110
  bool IsFinished() const { return end_ != NULL; }
110 111
  void AddPhi(HPhi* phi);
111 112
  void RemovePhi(HPhi* phi);
112
  void AddInstruction(HInstruction* instr);
113
  void AddInstruction(HInstruction* instr, int position);
113 114
  bool Dominates(HBasicBlock* other) const;
114 115
  int LoopNestingDepth() const;
115 116

  
......
132 133

  
133 134
  void SetJoinId(BailoutId ast_id);
134 135

  
135
  void Finish(HControlInstruction* last);
136
  void FinishExit(HControlInstruction* instruction);
137
  void Goto(HBasicBlock* block,
138
            FunctionState* state = NULL,
139
            bool add_simulate = true);
140
  void GotoNoSimulate(HBasicBlock* block) {
141
    Goto(block, NULL, false);
142
  }
143

  
144 136
  int PredecessorIndexOf(HBasicBlock* predecessor) const;
145 137
  HPhi* AddNewPhi(int merged_index);
146 138
  HSimulate* AddNewSimulate(BailoutId ast_id,
139
                            int position,
147 140
                            RemovableSimulate removable = FIXED_SIMULATE) {
148 141
    HSimulate* instr = CreateSimulate(ast_id, removable);
149
    AddInstruction(instr);
142
    AddInstruction(instr, position);
150 143
    return instr;
151 144
  }
152 145
  void AssignCommonDominator(HBasicBlock* other);
153 146
  void AssignLoopSuccessorDominators();
154 147

  
155
  // Add the inlined function exit sequence, adding an HLeaveInlined
156
  // instruction and updating the bailout environment.
157
  void AddLeaveInlined(HValue* return_value, FunctionState* state);
158

  
159 148
  // If a target block is tagged as an inline function return, all
160 149
  // predecessors should contain the inlined exit sequence:
161 150
  //
......
169 158
  }
170 159
  HBasicBlock* inlined_entry_block() { return inlined_entry_block_; }
171 160

  
172
  bool IsDeoptimizing() const { return is_deoptimizing_; }
173
  void MarkAsDeoptimizing() { is_deoptimizing_ = true; }
161
  bool IsDeoptimizing() const {
162
    return end() != NULL && end()->IsDeoptimize();
163
  }
164

  
165
  void MarkUnreachable();
166
  bool IsUnreachable() const { return !is_reachable_; }
167
  bool IsReachable() const { return is_reachable_; }
174 168

  
175 169
  bool IsLoopSuccessorDominator() const {
176 170
    return dominates_loop_successors_;
......
185 179
  void Verify();
186 180
#endif
187 181

  
188
 private:
182
 protected:
189 183
  friend class HGraphBuilder;
190 184

  
185
  HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
186
  void Finish(HControlInstruction* last, int position);
187
  void FinishExit(HControlInstruction* instruction, int position);
188
  void Goto(HBasicBlock* block,
189
            int position,
190
            FunctionState* state = NULL,
191
            bool add_simulate = true);
192
  void GotoNoSimulate(HBasicBlock* block, int position) {
193
    Goto(block, position, NULL, false);
194
  }
195

  
196
  // Add the inlined function exit sequence, adding an HLeaveInlined
197
  // instruction and updating the bailout environment.
198
  void AddLeaveInlined(HValue* return_value,
199
                       FunctionState* state,
200
                       int position);
201

  
202
 private:
191 203
  void RegisterPredecessor(HBasicBlock* pred);
192 204
  void AddDominatedBlock(HBasicBlock* block);
193 205

  
194
  HSimulate* CreateSimulate(BailoutId ast_id, RemovableSimulate removable);
195

  
196 206
  int block_id_;
197 207
  HGraph* graph_;
198 208
  ZoneList<HPhi*> phis_;
......
214 224
  // For blocks marked as inline return target: the block with HEnterInlined.
215 225
  HBasicBlock* inlined_entry_block_;
216 226
  bool is_inline_return_target_ : 1;
217
  bool is_deoptimizing_ : 1;
227
  bool is_reachable_ : 1;
218 228
  bool dominates_loop_successors_ : 1;
219 229
  bool is_osr_entry_ : 1;
220 230
};
......
316 326
  HBasicBlock* entry_block() const { return entry_block_; }
317 327
  HEnvironment* start_environment() const { return start_environment_; }
318 328

  
319
  void FinalizeUniqueValueIds();
329
  void FinalizeUniqueness();
320 330
  bool ProcessArgumentsObject();
321 331
  void OrderBlocks();
322 332
  void AssignDominators();
......
332 342

  
333 343
  void CollectPhis();
334 344

  
335
  void set_undefined_constant(HConstant* constant) {
336
    undefined_constant_.set(constant);
337
  }
338
  HConstant* GetConstantUndefined() const { return undefined_constant_.get(); }
345
  HConstant* GetConstantUndefined();
339 346
  HConstant* GetConstant0();
340 347
  HConstant* GetConstant1();
341 348
  HConstant* GetConstantMinus1();
......
405 412
    use_optimistic_licm_ = value;
406 413
  }
407 414

  
408
  bool has_soft_deoptimize() {
409
    return has_soft_deoptimize_;
410
  }
411

  
412
  void set_has_soft_deoptimize(bool value) {
413
    has_soft_deoptimize_ = value;
414
  }
415

  
416 415
  void MarkRecursive() {
417 416
    is_recursive_ = true;
418 417
  }
......
458 457
  bool IsInsideNoSideEffectsScope() { return no_side_effects_scope_count_ > 0; }
459 458

  
460 459
 private:
460
  HConstant* ReinsertConstantIfNecessary(HConstant* constant);
461 461
  HConstant* GetConstant(SetOncePointer<HConstant>* pointer,
462 462
                         int32_t integer_value);
463 463

  
......
477 477
  ZoneList<HValue*> values_;
478 478
  ZoneList<HPhi*>* phi_list_;
479 479
  ZoneList<HInstruction*>* uint32_instructions_;
480
  SetOncePointer<HConstant> undefined_constant_;
480
  SetOncePointer<HConstant> constant_undefined_;
481 481
  SetOncePointer<HConstant> constant_0_;
482 482
  SetOncePointer<HConstant> constant_1_;
483 483
  SetOncePointer<HConstant> constant_minus1_;
......
495 495

  
496 496
  bool is_recursive_;
497 497
  bool use_optimistic_licm_;
498
  bool has_soft_deoptimize_;
499 498
  bool depends_on_empty_array_proto_elements_;
500 499
  int type_change_checksum_;
501 500
  int maximum_environment_size_;
......
941 940

  
942 941
class HIfContinuation V8_FINAL {
943 942
 public:
944
  HIfContinuation() { continuation_captured_ = false; }
943
  HIfContinuation() : continuation_captured_(false) {}
944
  HIfContinuation(HBasicBlock* true_branch,
945
                  HBasicBlock* false_branch)
946
      : continuation_captured_(true), true_branch_(true_branch),
947
        false_branch_(false_branch) {}
945 948
  ~HIfContinuation() { ASSERT(!continuation_captured_); }
946 949

  
947 950
  void Capture(HBasicBlock* true_branch,
948
               HBasicBlock* false_branch,
949
               int position) {
951
               HBasicBlock* false_branch) {
950 952
    ASSERT(!continuation_captured_);
951 953
    true_branch_ = true_branch;
952 954
    false_branch_ = false_branch;
953
    position_ = position;
954 955
    continuation_captured_ = true;
955 956
  }
956 957

  
957 958
  void Continue(HBasicBlock** true_branch,
958
                HBasicBlock** false_branch,
959
                int* position) {
959
                HBasicBlock** false_branch) {
960 960
    ASSERT(continuation_captured_);
961 961
    *true_branch = true_branch_;
962 962
    *false_branch = false_branch_;
963
    if (position != NULL) *position = position_;
964 963
    continuation_captured_ = false;
965 964
  }
966 965

  
......
970 969
    return IsTrueReachable() || IsFalseReachable();
971 970
  }
972 971

  
972
  HBasicBlock* true_branch() const { return true_branch_; }
973
  HBasicBlock* false_branch() const { return false_branch_; }
974

  
975
 private:
973 976
  bool continuation_captured_;
974 977
  HBasicBlock* true_branch_;
975 978
  HBasicBlock* false_branch_;
976
  int position_;
977 979
};
978 980

  
979 981

  
......
982 984
  explicit HGraphBuilder(CompilationInfo* info)
983 985
      : info_(info),
984 986
        graph_(NULL),
985
        current_block_(NULL) {}
987
        current_block_(NULL),
988
        position_(RelocInfo::kNoPosition) {}
986 989
  virtual ~HGraphBuilder() {}
987 990

  
988 991
  HBasicBlock* current_block() const { return current_block_; }
......
1005 1008

  
1006 1009
  // Adding instructions.
1007 1010
  HInstruction* AddInstruction(HInstruction* instr);
1011
  void FinishCurrentBlock(HControlInstruction* last);
1012
  void FinishExitCurrentBlock(HControlInstruction* instruction);
1013

  
1014
  void Goto(HBasicBlock* from,
1015
            HBasicBlock* target,
1016
            FunctionState* state = NULL,
1017
            bool add_simulate = true) {
1018
    from->Goto(target, position_, state, add_simulate);
1019
  }
1020
  void Goto(HBasicBlock* target,
1021
            FunctionState* state = NULL,
1022
            bool add_simulate = true) {
1023
    Goto(current_block(), target, state, add_simulate);
1024
  }
1025
  void GotoNoSimulate(HBasicBlock* from, HBasicBlock* target) {
1026
    Goto(from, target, NULL, false);
1027
  }
1028
  void GotoNoSimulate(HBasicBlock* target) {
1029
    Goto(target, NULL, false);
1030
  }
1031
  void AddLeaveInlined(HBasicBlock* block,
1032
                       HValue* return_value,
1033
                       FunctionState* state) {
1034
    block->AddLeaveInlined(return_value, state, position_);
1035
  }
1036
  void AddLeaveInlined(HValue* return_value, FunctionState* state) {
1037
    return AddLeaveInlined(current_block(), return_value, state);
1038
  }
1008 1039

  
1009 1040
  template<class I>
1010 1041
  HInstruction* NewUncasted() { return I::New(zone(), context()); }
......
1199 1230

  
1200 1231
  void AddSimulate(BailoutId id, RemovableSimulate removable = FIXED_SIMULATE);
1201 1232

  
1233
  int position() const { return position_; }
1234

  
1202 1235
 protected:
1203 1236
  virtual bool BuildGraph() = 0;
1204 1237

  
......
1228 1261
                                   ElementsKind to_kind,
1229 1262
                                   bool is_jsarray);
1230 1263

  
1264
  HValue* BuildNumberToString(HValue* object, Handle<Type> type);
1265

  
1231 1266
  HInstruction* BuildUncheckedMonomorphicElementAccess(
1232 1267
      HValue* checked_object,
1233 1268
      HValue* key,
......
1238 1273
      LoadKeyedHoleMode load_mode,
1239 1274
      KeyedAccessStoreMode store_mode);
1240 1275

  
1241
  HInstruction* AddExternalArrayElementAccess(
1242
      HValue* external_elements,
1243
      HValue* checked_key,
1244
      HValue* val,
1245
      HValue* dependency,
1246
      ElementsKind elements_kind,
1247
      bool is_store);
1248

  
1249
  HInstruction* AddFastElementAccess(
1276
  HInstruction* AddElementAccess(
1250 1277
      HValue* elements,
1251 1278
      HValue* checked_key,
1252 1279
      HValue* val,
1253 1280
      HValue* dependency,
1254 1281
      ElementsKind elements_kind,
1255 1282
      bool is_store,
1256
      LoadKeyedHoleMode load_mode,
1257
      KeyedAccessStoreMode store_mode);
1283
      LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
1258 1284

  
1259 1285
  HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access);
1286
  HInstruction* AddLoadNamedField(HValue* object, HObjectAccess access);
1260 1287
  HInstruction* BuildLoadStringLength(HValue* object, HValue* checked_value);
1261 1288
  HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map>);
1262 1289
  HLoadNamedField* AddLoadElements(HValue* object);
1290

  
1291
  bool MatchRotateRight(HValue* left,
1292
                        HValue* right,
1293
                        HValue** operand,
1294
                        HValue** shift_amount);
1295

  
1296
  HInstruction* BuildBinaryOperation(Token::Value op,
1297
                                     HValue* left,
1298
                                     HValue* right,
1299
                                     Handle<Type> left_type,
1300
                                     Handle<Type> right_type,
1301
                                     Handle<Type> result_type,
1302
                                     Maybe<int> fixed_right_arg,
1303
                                     bool binop_stub = false);
1304

  
1263 1305
  HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
1264 1306

  
1265 1307
  HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin);
1266 1308

  
1309
  HValue* EnforceNumberType(HValue* number, Handle<Type> expected);
1267 1310
  HValue* TruncateToNumber(HValue* value, Handle<Type>* expected);
1268 1311

  
1269
  void PushAndAdd(HInstruction* instr);
1270

  
1271 1312
  void FinishExitWithHardDeoptimization(const char* reason,
1272 1313
                                        HBasicBlock* continuation);
1273 1314

  
1274
  void AddIncrementCounter(StatsCounter* counter,
1275
                           HValue* context);
1315
  void AddIncrementCounter(StatsCounter* counter);
1276 1316

  
1277 1317
  class IfBuilder V8_FINAL {
1278 1318
   public:
1279
    explicit IfBuilder(HGraphBuilder* builder,
1280
                       int position = RelocInfo::kNoPosition);
1319
    explicit IfBuilder(HGraphBuilder* builder);
1281 1320
    IfBuilder(HGraphBuilder* builder,
1282 1321
              HIfContinuation* continuation);
1283 1322

  
......
1286 1325
    }
1287 1326

  
1288 1327
    template<class Condition>
1289
    HInstruction* If(HValue *p) {
1290
      HControlInstruction* compare = new(zone()) Condition(p);
1328
    Condition* If(HValue *p) {
1329
      Condition* compare = builder()->New<Condition>(p);
1291 1330
      AddCompare(compare);
1292 1331
      return compare;
1293 1332
    }
1294 1333

  
1295 1334
    template<class Condition, class P2>
1296
    HInstruction* If(HValue* p1, P2 p2) {
1297
      HControlInstruction* compare = new(zone()) Condition(p1, p2);
1335
    Condition* If(HValue* p1, P2 p2) {
1336
      Condition* compare = builder()->New<Condition>(p1, p2);
1298 1337
      AddCompare(compare);
1299 1338
      return compare;
1300 1339
    }
1301 1340

  
1302 1341
    template<class Condition, class P2, class P3>
1303
    HInstruction* If(HValue* p1, P2 p2, P3 p3) {
1304
      HControlInstruction* compare = new(zone()) Condition(p1, p2, p3);
1342
    Condition* If(HValue* p1, P2 p2, P3 p3) {
1343
      Condition* compare = builder()->New<Condition>(p1, p2, p3);
1305 1344
      AddCompare(compare);
1306 1345
      return compare;
1307 1346
    }
1308 1347

  
1348
    template<class Condition>
1349
    Condition* IfNot(HValue* p) {
1350
      Condition* compare = If<Condition>(p);
1351
      compare->Not();
1352
      return compare;
1353
    }
1354

  
1309 1355
    template<class Condition, class P2>
1310
    HInstruction* IfNot(HValue* p1, P2 p2) {
1311
      HControlInstruction* compare = new(zone()) Condition(p1, p2);
1312
      AddCompare(compare);
1313
      HBasicBlock* block0 = compare->SuccessorAt(0);
1314
      HBasicBlock* block1 = compare->SuccessorAt(1);
1315
      compare->SetSuccessorAt(0, block1);
1316
      compare->SetSuccessorAt(1, block0);
1356
    Condition* IfNot(HValue* p1, P2 p2) {
1357
      Condition* compare = If<Condition>(p1, p2);
1358
      compare->Not();
1317 1359
      return compare;
1318 1360
    }
1319 1361

  
1320 1362
    template<class Condition, class P2, class P3>
1321
    HInstruction* IfNot(HValue* p1, P2 p2, P3 p3) {
1322
      HControlInstruction* compare = new(zone()) Condition(p1, p2, p3);
1323
      AddCompare(compare);
1324
      HBasicBlock* block0 = compare->SuccessorAt(0);
1325
      HBasicBlock* block1 = compare->SuccessorAt(1);
1326
      compare->SetSuccessorAt(0, block1);
1327
      compare->SetSuccessorAt(1, block0);
1363
    Condition* IfNot(HValue* p1, P2 p2, P3 p3) {
1364
      Condition* compare = If<Condition>(p1, p2, p3);
1365
      compare->Not();
1328 1366
      return compare;
1329 1367
    }
1330 1368

  
1331 1369
    template<class Condition>
1332
    HInstruction* OrIf(HValue *p) {
1370
    Condition* OrIf(HValue *p) {
1333 1371
      Or();
1334 1372
      return If<Condition>(p);
1335 1373
    }
1336 1374

  
1337 1375
    template<class Condition, class P2>
1338
    HInstruction* OrIf(HValue* p1, P2 p2) {
1376
    Condition* OrIf(HValue* p1, P2 p2) {
1339 1377
      Or();
1340 1378
      return If<Condition>(p1, p2);
1341 1379
    }
1342 1380

  
1343 1381
    template<class Condition, class P2, class P3>
1344
    HInstruction* OrIf(HValue* p1, P2 p2, P3 p3) {
1382
    Condition* OrIf(HValue* p1, P2 p2, P3 p3) {
1345 1383
      Or();
1346 1384
      return If<Condition>(p1, p2, p3);
1347 1385
    }
1348 1386

  
1349 1387
    template<class Condition>
1350
    HInstruction* AndIf(HValue *p) {
1388
    Condition* AndIf(HValue *p) {
1351 1389
      And();
1352 1390
      return If<Condition>(p);
1353 1391
    }
1354 1392

  
1355 1393
    template<class Condition, class P2>
1356
    HInstruction* AndIf(HValue* p1, P2 p2) {
1394
    Condition* AndIf(HValue* p1, P2 p2) {
1357 1395
      And();
1358 1396
      return If<Condition>(p1, p2);
1359 1397
    }
1360 1398

  
1361 1399
    template<class Condition, class P2, class P3>
1362
    HInstruction* AndIf(HValue* p1, P2 p2, P3 p3) {
1400
    Condition* AndIf(HValue* p1, P2 p2, P3 p3) {
1363 1401
      And();
1364 1402
      return If<Condition>(p1, p2, p3);
1365 1403
    }
......
1367 1405
    void Or();
1368 1406
    void And();
1369 1407

  
1408
    // Captures the current state of this IfBuilder in the specified
1409
    // continuation and ends this IfBuilder.
1370 1410
    void CaptureContinuation(HIfContinuation* continuation);
1371 1411

  
1412
    // Joins the specified continuation from this IfBuilder and ends this
1413
    // IfBuilder. This appends a Goto instruction from the true branch of
1414
    // this IfBuilder to the true branch of the continuation unless the
1415
    // true branch of this IfBuilder is already finished. And vice versa
1416
    // for the false branch.
1417
    //
1418
    // The basic idea is as follows: You have several nested IfBuilder's
1419
    // that you want to join based on two possible outcomes (i.e. success
1420
    // and failure, or whatever). You can do this easily using this method
1421
    // now, for example:
1422
    //
1423
    //   HIfContinuation cont(graph()->CreateBasicBlock(),
1424
    //                        graph()->CreateBasicBlock());
1425
    //   ...
1426
    //     IfBuilder if_whatever(this);
1427
    //     if_whatever.If<Condition>(arg);
1428
    //     if_whatever.Then();
1429
    //     ...
1430
    //     if_whatever.Else();
1431
    //     ...
1432
    //     if_whatever.JoinContinuation(&cont);
1433
    //   ...
1434
    //     IfBuilder if_something(this);
1435
    //     if_something.If<Condition>(arg1, arg2);
1436
    //     if_something.Then();
1437
    //     ...
1438
    //     if_something.Else();
1439
    //     ...
1440
    //     if_something.JoinContinuation(&cont);
1441
    //   ...
1442
    //   IfBuilder if_finally(this, &cont);
1443
    //   if_finally.Then();
1444
    //   // continues after then code of if_whatever or if_something.
1445
    //   ...
1446
    //   if_finally.Else();
1447
    //   // continues after else code of if_whatever or if_something.
1448
    //   ...
1449
    //   if_finally.End();
1450
    void JoinContinuation(HIfContinuation* continuation);
1451

  
1372 1452
    void Then();
1373 1453
    void Else();
1374 1454
    void End();
......
1382 1462
    void Return(HValue* value);
1383 1463

  
1384 1464
   private:
1385
    void AddCompare(HControlInstruction* compare);
1465
    HControlInstruction* AddCompare(HControlInstruction* compare);
1386 1466

  
1387
    Zone* zone() { return builder_->zone(); }
1467
    HGraphBuilder* builder() const { return builder_; }
1388 1468

  
1389 1469
    HGraphBuilder* builder_;
1390
    int position_;
1391 1470
    bool finished_ : 1;
1392 1471
    bool deopt_then_ : 1;
1393 1472
    bool deopt_else_ : 1;
......
1548 1627
  void BuildCompareNil(
1549 1628
      HValue* value,
1550 1629
      Handle<Type> type,
1551
      int position,
1552 1630
      HIfContinuation* continuation);
1553 1631

  
1554 1632
  HValue* BuildCreateAllocationMemento(HValue* previous_object,
......
1563 1641
  HInstruction* BuildGetNativeContext();
1564 1642
  HInstruction* BuildGetArrayFunction();
1565 1643

  
1644
 protected:
1645
  void SetSourcePosition(int position) {
1646
    ASSERT(position != RelocInfo::kNoPosition);
1647
    position_ = position;
1648
  }
1649

  
1566 1650
 private:
1567 1651
  HGraphBuilder();
1568 1652

  
......
1572 1656
  CompilationInfo* info_;
1573 1657
  HGraph* graph_;
1574 1658
  HBasicBlock* current_block_;
1659
  int position_;
1575 1660
};
1576 1661

  
1577 1662

  
......
1583 1668
    if (FLAG_always_opt) return NULL;
1584 1669
  }
1585 1670
  if (current_block()->IsDeoptimizing()) return NULL;
1586
  HDeoptimize* instr = New<HDeoptimize>(reason, type);
1587
  AddInstruction(instr);
1671
  HBasicBlock* after_deopt_block = CreateBasicBlock(
1672
      current_block()->last_environment());
1673
  HDeoptimize* instr = New<HDeoptimize>(reason, type, after_deopt_block);
1588 1674
  if (type == Deoptimizer::SOFT) {
1589 1675
    isolate()->counters()->soft_deopts_inserted()->Increment();
1590
    graph()->set_has_soft_deoptimize(true);
1591 1676
  }
1592
  current_block()->MarkAsDeoptimizing();
1677
  FinishCurrentBlock(instr);
1678
  set_current_block(after_deopt_block);
1593 1679
  return instr;
1594 1680
}
1595 1681

  
......
1622 1708
  int num_parameters = graph()->info()->num_parameters();
1623 1709
  HValue* params = AddUncasted<HConstant>(num_parameters);
1624 1710
  HReturn* return_instruction = New<HReturn>(value, params);
1625
  current_block()->FinishExit(return_instruction);
1711
  FinishExitCurrentBlock(return_instruction);
1626 1712
  return return_instruction;
1627 1713
}
1628 1714

  
......
1634 1720

  
1635 1721

  
1636 1722
template<>
1723
inline HInstruction* HGraphBuilder::AddUncasted<HCallRuntime>(
1724
    Handle<String> name,
1725
    const Runtime::Function* c_function,
1726
    int argument_count) {
1727
  HCallRuntime* instr = New<HCallRuntime>(name, c_function, argument_count);
1728
  if (graph()->info()->IsStub()) {
1729
    // When compiling code stubs, we don't want to save all double registers
1730
    // upon entry to the stub, but instead have the call runtime instruction
1731
    // save the double registers only on-demand (in the fallback case).
1732
    instr->set_save_doubles(kSaveFPRegs);
1733
  }
1734
  AddInstruction(instr);
1735
  return instr;
1736
}
1737

  
1738

  
1739
template<>
1637 1740
inline HInstruction* HGraphBuilder::NewUncasted<HContext>() {
1638 1741
  return HContext::New(zone());
1639 1742
}
1640 1743

  
1641 1744

  
1642
class HOptimizedGraphBuilder V8_FINAL
1643
    : public HGraphBuilder, public AstVisitor {
1745
class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
1644 1746
 public:
1645 1747
  // A class encapsulating (lazily-allocated) break and continue blocks for
1646 1748
  // a breakable statement.  Separated from BreakAndContinueScope so that it
......
1707 1809

  
1708 1810
  HValue* context() { return environment()->context(); }
1709 1811

  
1812
  HOsrBuilder* osr() const { return osr_; }
1813

  
1710 1814
  void Bailout(BailoutReason reason);
1711 1815

  
1712 1816
  HBasicBlock* CreateJoin(HBasicBlock* first,
......
1725 1829

  
1726 1830
  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
1727 1831

  
1728
 private:
1832
 protected:
1729 1833
  // Type of a member function that generates inline code for a native function.
1730 1834
  typedef void (HOptimizedGraphBuilder::*InlineFunctionGenerator)
1731 1835
      (CallRuntime* call);
......
1812 1916
                          HBasicBlock* loop_successor,
1813 1917
                          HBasicBlock* break_block);
1814 1918

  
1919
  // Build a loop entry
1920
  HBasicBlock* BuildLoopEntry();
1921

  
1922
  // Builds a loop entry respectful of OSR requirements
1923
  HBasicBlock* BuildLoopEntry(IterationStatement* statement);
1924

  
1815 1925
  HBasicBlock* JoinContinue(IterationStatement* statement,
1816 1926
                            HBasicBlock* exit_block,
1817 1927
                            HBasicBlock* continue_block);
......
1837 1947
    env->Bind(index, value);
1838 1948
    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
1839 1949
      HEnvironmentMarker* bind =
1840
          new(zone()) HEnvironmentMarker(HEnvironmentMarker::BIND, index);
1841
      AddInstruction(bind);
1950
          Add<HEnvironmentMarker>(HEnvironmentMarker::BIND, index);
1951
      USE(bind);
1842 1952
#ifdef DEBUG
1843 1953
      bind->set_closure(env->closure());
1844 1954
#endif
1845 1955
    }
1846 1956
  }
1957

  
1847 1958
  HValue* LookupAndMakeLive(Variable* var) {
1848 1959
    HEnvironment* env = environment();
1849 1960
    int index = env->IndexFor(var);
1850 1961
    HValue* value = env->Lookup(index);
1851 1962
    if (IsEligibleForEnvironmentLivenessAnalysis(var, index, value, env)) {
1852 1963
      HEnvironmentMarker* lookup =
1853
          new(zone()) HEnvironmentMarker(HEnvironmentMarker::LOOKUP, index);
1854
      AddInstruction(lookup);
1964
          Add<HEnvironmentMarker>(HEnvironmentMarker::LOOKUP, index);
1965
      USE(lookup);
1855 1966
#ifdef DEBUG
1856 1967
      lookup->set_closure(env->closure());
1857 1968
#endif
......
1889 2000
  AST_NODE_LIST(DECLARE_VISIT)
1890 2001
#undef DECLARE_VISIT
1891 2002

  
2003
 private:
1892 2004
  // Helpers for flow graph construction.
1893 2005
  enum GlobalPropertyAccess {
1894 2006
    kUseCell,
......
1940 2052

  
1941 2053
  void HandleGlobalVariableAssignment(Variable* var,
1942 2054
                                      HValue* value,
1943
                                      int position,
1944 2055
                                      BailoutId ast_id);
1945 2056

  
1946 2057
  void HandlePropertyAssignment(Assignment* expr);
1947 2058
  void HandleCompoundAssignment(Assignment* expr);
1948
  void HandlePolymorphicLoadNamedField(int position,
2059
  void HandlePolymorphicLoadNamedField(BailoutId ast_id,
1949 2060
                                       BailoutId return_id,
1950 2061
                                       HValue* object,
1951 2062
                                       SmallMapList* types,
1952 2063
                                       Handle<String> name);
1953
  HInstruction* TryLoadPolymorphicAsMonomorphic(HValue* object,
1954
                                                SmallMapList* types,
1955
                                                Handle<String> name);
1956
  void HandlePolymorphicStoreNamedField(int position,
1957
                                        BailoutId assignment_id,
2064

  
2065
  class PropertyAccessInfo {
2066
   public:
2067
    PropertyAccessInfo(Isolate* isolate, Handle<Map> map, Handle<String> name)
2068
        : lookup_(isolate),
2069
          map_(map),
2070
          name_(name),
2071
          access_(HObjectAccess::ForMap()) { }
2072

  
2073
    // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
2074
    // load named. It additionally fills in the fields necessary to generate the
2075
    // lookup code.
2076
    bool CanLoadMonomorphic();
2077

  
2078
    // Checks whether all types behave uniform when loading name. If all maps
2079
    // behave the same, a single monomorphic load instruction can be emitted,
2080
    // guarded by a single map-checks instruction that whether the receiver is
2081
    // an instance of any of the types.
2082
    // This method skips the first type in types, assuming that this
2083
    // PropertyAccessInfo is built for types->first().
2084
    bool CanLoadAsMonomorphic(SmallMapList* types);
2085

  
2086
    bool IsJSObjectFieldAccessor() {
2087
      int offset;  // unused
2088
      return Accessors::IsJSObjectFieldAccessor(map_, name_, &offset);
2089
    }
2090

  
2091
    bool GetJSObjectFieldAccess(HObjectAccess* access) {
2092
      if (IsStringLength()) {
2093
        *access = HObjectAccess::ForStringLength();
2094
        return true;
2095
      } else if (IsArrayLength()) {
2096
        *access = HObjectAccess::ForArrayLength(map_->elements_kind());
2097
        return true;
2098
      } else {
2099
        int offset;
2100
        if (Accessors::IsJSObjectFieldAccessor(map_, name_, &offset)) {
2101
          *access = HObjectAccess::ForJSObjectOffset(offset);
2102
          return true;
2103
        }
2104
        return false;
2105
      }
2106
    }
2107

  
2108
    bool has_holder() { return !holder_.is_null(); }
2109

  
2110
    LookupResult* lookup() { return &lookup_; }
2111
    Handle<Map> map() { return map_; }
2112
    Handle<JSObject> holder() { return holder_; }
2113
    Handle<JSFunction> accessor() { return accessor_; }
2114
    Handle<Object> constant() { return constant_; }
2115
    HObjectAccess access() { return access_; }
2116

  
2117
   private:
2118
    Isolate* isolate() { return lookup_.isolate(); }
2119

  
2120
    bool IsStringLength() {
2121
      return map_->instance_type() < FIRST_NONSTRING_TYPE &&
2122
          name_->Equals(isolate()->heap()->length_string());
2123
    }
2124

  
2125
    bool IsArrayLength() {
2126
      return map_->instance_type() == JS_ARRAY_TYPE &&
2127
          name_->Equals(isolate()->heap()->length_string());
2128
    }
2129

  
2130
    bool LoadResult(Handle<Map> map);
2131
    bool LookupDescriptor();
2132
    bool LookupInPrototypes();
2133
    bool IsCompatibleForLoad(PropertyAccessInfo* other);
2134

  
2135
    void GeneralizeRepresentation(Representation r) {
2136
      access_ = access_.WithRepresentation(
2137
          access_.representation().generalize(r));
2138
    }
2139

  
2140
    LookupResult lookup_;
2141
    Handle<Map> map_;
2142
    Handle<String> name_;
2143
    Handle<JSObject> holder_;
2144
    Handle<JSFunction> accessor_;
2145
    Handle<Object> constant_;
2146
    HObjectAccess access_;
2147
  };
2148

  
2149
  HInstruction* BuildLoadMonomorphic(PropertyAccessInfo* info,
2150
                                     HValue* object,
2151
                                     HInstruction* checked_object,
2152
                                     BailoutId ast_id,
2153
                                     BailoutId return_id,
2154
                                     bool can_inline_accessor = true);
2155

  
2156
  void HandlePolymorphicStoreNamedField(BailoutId assignment_id,
1958 2157
                                        HValue* object,
1959 2158
                                        HValue* value,
1960 2159
                                        SmallMapList* types,
1961 2160
                                        Handle<String> name);
1962
  bool TryStorePolymorphicAsMonomorphic(int position,
1963
                                        BailoutId assignment_id,
2161
  bool TryStorePolymorphicAsMonomorphic(BailoutId assignment_id,
1964 2162
                                        HValue* object,
1965 2163
                                        HValue* value,
1966 2164
                                        SmallMapList* types,
......
2009 2207
                                         HValue* key,
2010 2208
                                         HValue* val,
2011 2209
                                         SmallMapList* maps,
2012
                                         BailoutId ast_id,
2013
                                         int position,
2014 2210
                                         bool is_store,
2015 2211
                                         KeyedAccessStoreMode store_mode,
2016 2212
                                         bool* has_side_effects);
......
2019 2215
                                   HValue* key,
2020 2216
                                   HValue* val,
2021 2217
                                   Expression* expr,
2022
                                   BailoutId ast_id,
2023
                                   int position,
2024 2218
                                   bool is_store,
2025 2219
                                   bool* has_side_effects);
2026 2220

  
2027 2221
  HInstruction* BuildLoadNamedGeneric(HValue* object,
2028 2222
                                      Handle<String> name,
2029 2223
                                      Property* expr);
2030
  HInstruction* BuildCallGetter(HValue* object,
2031
                                Handle<Map> map,
2032
                                Handle<JSFunction> getter,
2033
                                Handle<JSObject> holder);
2034
  HInstruction* BuildLoadNamedMonomorphic(HValue* object,
2035
                                          Handle<String> name,
2036
                                          Handle<Map> map);
2037 2224

  
2038 2225
  HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
2039 2226

  
2040 2227
  void BuildLoad(Property* property,
2041
                 int position,
2042 2228
                 BailoutId ast_id);
2043 2229
  void PushLoad(Property* property,
2044 2230
                HValue* object,
2045
                HValue* key,
2046
                int position);
2231
                HValue* key);
2047 2232

  
2048 2233
  void BuildStoreForEffect(Expression* expression,
2049 2234
                           Property* prop,
......
2080 2265
  HInstruction* BuildThisFunction();
2081 2266

  
2082 2267
  HInstruction* BuildFastLiteral(Handle<JSObject> boilerplate_object,
2083
                                 Handle<Object> allocation_site,
2084
                                 AllocationSiteMode mode);
2268
                                 AllocationSiteContext* site_context);
2085 2269

  
2086 2270
  void BuildEmitObjectHeader(Handle<JSObject> boilerplate_object,
2087 2271
                             HInstruction* object);
......
2091 2275
                                       HInstruction* object_elements);
2092 2276

  
2093 2277
  void BuildEmitInObjectProperties(Handle<JSObject> boilerplate_object,
2094
                                   HInstruction* object);
2278
                                   HInstruction* object,
2279
                                   AllocationSiteContext* site_context);
2095 2280

  
2096 2281
  void BuildEmitElements(Handle<JSObject> boilerplate_object,
2097 2282
                         Handle<FixedArrayBase> elements,
2098
                         HValue* object_elements);
2283
                         HValue* object_elements,
2284
                         AllocationSiteContext* site_context);
2099 2285

  
2100 2286
  void BuildEmitFixedDoubleArray(Handle<FixedArrayBase> elements,
2101 2287
                                 ElementsKind kind,
......
2103 2289

  
2104 2290
  void BuildEmitFixedArray(Handle<FixedArrayBase> elements,
2105 2291
                           ElementsKind kind,
2106
                           HValue* object_elements);
2292
                           HValue* object_elements,
2293
                           AllocationSiteContext* site_context);
2107 2294

  
2108 2295
  void AddCheckPrototypeMaps(Handle<JSObject> holder,
2109 2296
                             Handle<Map> receiver_map);
......
2112 2299
                                HValue* receiver,
2113 2300
                                Handle<Map> receiver_map);
2114 2301

  
2115
  bool MatchRotateRight(HValue* left,
2116
                        HValue* right,
2117
                        HValue** operand,
2118
                        HValue** shift_amount);
2119

  
2120 2302
  // The translation state of the currently-being-translated function.
2121 2303
  FunctionState* function_state_;
2122 2304

  

Also available in: Unified diff