The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / lithium-allocator.h @ f230a1cf

History | View | Annotate | Download (20.8 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_LITHIUM_ALLOCATOR_H_
29
#define V8_LITHIUM_ALLOCATOR_H_
30

    
31
#include "v8.h"
32

    
33
#include "allocation.h"
34
#include "lithium.h"
35
#include "zone.h"
36

    
37
namespace v8 {
38
namespace internal {
39

    
40
// Forward declarations.
41
class HBasicBlock;
42
class HGraph;
43
class HInstruction;
44
class HPhi;
45
class HTracer;
46
class HValue;
47
class BitVector;
48
class StringStream;
49

    
50
class LArgument;
51
class LPlatformChunk;
52
class LOperand;
53
class LUnallocated;
54
class LConstantOperand;
55
class LGap;
56
class LParallelMove;
57
class LPointerMap;
58
class LStackSlot;
59
class LRegister;
60

    
61

    
62
// This class represents a single point of a LOperand's lifetime.
63
// For each lithium instruction there are exactly two lifetime positions:
64
// the beginning and the end of the instruction. Lifetime positions for
65
// different lithium instructions are disjoint.
66
class LifetimePosition {
67
 public:
68
  // Return the lifetime position that corresponds to the beginning of
69
  // the instruction with the given index.
70
  static LifetimePosition FromInstructionIndex(int index) {
71
    return LifetimePosition(index * kStep);
72
  }
73

    
74
  // Returns a numeric representation of this lifetime position.
75
  int Value() const {
76
    return value_;
77
  }
78

    
79
  // Returns the index of the instruction to which this lifetime position
80
  // corresponds.
81
  int InstructionIndex() const {
82
    ASSERT(IsValid());
83
    return value_ / kStep;
84
  }
85

    
86
  // Returns true if this lifetime position corresponds to the instruction
87
  // start.
88
  bool IsInstructionStart() const {
89
    return (value_ & (kStep - 1)) == 0;
90
  }
91

    
92
  // Returns the lifetime position for the start of the instruction which
93
  // corresponds to this lifetime position.
94
  LifetimePosition InstructionStart() const {
95
    ASSERT(IsValid());
96
    return LifetimePosition(value_ & ~(kStep - 1));
97
  }
98

    
99
  // Returns the lifetime position for the end of the instruction which
100
  // corresponds to this lifetime position.
101
  LifetimePosition InstructionEnd() const {
102
    ASSERT(IsValid());
103
    return LifetimePosition(InstructionStart().Value() + kStep/2);
104
  }
105

    
106
  // Returns the lifetime position for the beginning of the next instruction.
107
  LifetimePosition NextInstruction() const {
108
    ASSERT(IsValid());
109
    return LifetimePosition(InstructionStart().Value() + kStep);
110
  }
111

    
112
  // Returns the lifetime position for the beginning of the previous
113
  // instruction.
114
  LifetimePosition PrevInstruction() const {
115
    ASSERT(IsValid());
116
    ASSERT(value_ > 1);
117
    return LifetimePosition(InstructionStart().Value() - kStep);
118
  }
119

    
120
  // Constructs the lifetime position which does not correspond to any
121
  // instruction.
122
  LifetimePosition() : value_(-1) {}
123

    
124
  // Returns true if this lifetime positions corrensponds to some
125
  // instruction.
126
  bool IsValid() const { return value_ != -1; }
127

    
128
  static inline LifetimePosition Invalid() { return LifetimePosition(); }
129

    
130
  static inline LifetimePosition MaxPosition() {
131
    // We have to use this kind of getter instead of static member due to
132
    // crash bug in GDB.
133
    return LifetimePosition(kMaxInt);
134
  }
135

    
136
 private:
137
  static const int kStep = 2;
138

    
139
  // Code relies on kStep being a power of two.
140
  STATIC_ASSERT(IS_POWER_OF_TWO(kStep));
141

    
142
  explicit LifetimePosition(int value) : value_(value) { }
143

    
144
  int value_;
145
};
146

    
147

    
148
enum RegisterKind {
149
  UNALLOCATED_REGISTERS,
150
  GENERAL_REGISTERS,
151
  DOUBLE_REGISTERS
152
};
153

    
154

    
155
// A register-allocator view of a Lithium instruction. It contains the id of
156
// the output operand and a list of input operand uses.
157

    
158
class LInstruction;
159
class LEnvironment;
160

    
161
// Iterator for non-null temp operands.
162
class TempIterator BASE_EMBEDDED {
163
 public:
164
  inline explicit TempIterator(LInstruction* instr);
165
  inline bool Done();
166
  inline LOperand* Current();
167
  inline void Advance();
168

    
169
 private:
170
  inline void SkipUninteresting();
171
  LInstruction* instr_;
172
  int limit_;
173
  int current_;
174
};
175

    
176

    
177
// Iterator for non-constant input operands.
178
class InputIterator BASE_EMBEDDED {
179
 public:
180
  inline explicit InputIterator(LInstruction* instr);
181
  inline bool Done();
182
  inline LOperand* Current();
183
  inline void Advance();
184

    
185
 private:
186
  inline void SkipUninteresting();
187
  LInstruction* instr_;
188
  int limit_;
189
  int current_;
190
};
191

    
192

    
193
class UseIterator BASE_EMBEDDED {
194
 public:
195
  inline explicit UseIterator(LInstruction* instr);
196
  inline bool Done();
197
  inline LOperand* Current();
198
  inline void Advance();
199

    
200
 private:
201
  InputIterator input_iterator_;
202
  DeepIterator env_iterator_;
203
};
204

    
205

    
206
// Representation of the non-empty interval [start,end[.
207
class UseInterval: public ZoneObject {
208
 public:
209
  UseInterval(LifetimePosition start, LifetimePosition end)
210
      : start_(start), end_(end), next_(NULL) {
211
    ASSERT(start.Value() < end.Value());
212
  }
213

    
214
  LifetimePosition start() const { return start_; }
215
  LifetimePosition end() const { return end_; }
216
  UseInterval* next() const { return next_; }
217

    
218
  // Split this interval at the given position without effecting the
219
  // live range that owns it. The interval must contain the position.
220
  void SplitAt(LifetimePosition pos, Zone* zone);
221

    
222
  // If this interval intersects with other return smallest position
223
  // that belongs to both of them.
224
  LifetimePosition Intersect(const UseInterval* other) const {
225
    if (other->start().Value() < start_.Value()) return other->Intersect(this);
226
    if (other->start().Value() < end_.Value()) return other->start();
227
    return LifetimePosition::Invalid();
228
  }
229

    
230
  bool Contains(LifetimePosition point) const {
231
    return start_.Value() <= point.Value() && point.Value() < end_.Value();
232
  }
233

    
234
 private:
235
  void set_start(LifetimePosition start) { start_ = start; }
236
  void set_next(UseInterval* next) { next_ = next; }
237

    
238
  LifetimePosition start_;
239
  LifetimePosition end_;
240
  UseInterval* next_;
241

    
242
  friend class LiveRange;  // Assigns to start_.
243
};
244

    
245
// Representation of a use position.
246
class UsePosition: public ZoneObject {
247
 public:
248
  UsePosition(LifetimePosition pos, LOperand* operand, LOperand* hint);
249

    
250
  LOperand* operand() const { return operand_; }
251
  bool HasOperand() const { return operand_ != NULL; }
252

    
253
  LOperand* hint() const { return hint_; }
254
  bool HasHint() const;
255
  bool RequiresRegister() const;
256
  bool RegisterIsBeneficial() const;
257

    
258
  LifetimePosition pos() const { return pos_; }
259
  UsePosition* next() const { return next_; }
260

    
261
 private:
262
  void set_next(UsePosition* next) { next_ = next; }
263

    
264
  LOperand* const operand_;
265
  LOperand* const hint_;
266
  LifetimePosition const pos_;
267
  UsePosition* next_;
268
  bool requires_reg_;
269
  bool register_beneficial_;
270

    
271
  friend class LiveRange;
272
};
273

    
274
// Representation of SSA values' live ranges as a collection of (continuous)
275
// intervals over the instruction ordering.
276
class LiveRange: public ZoneObject {
277
 public:
278
  static const int kInvalidAssignment = 0x7fffffff;
279

    
280
  LiveRange(int id, Zone* zone);
281

    
282
  UseInterval* first_interval() const { return first_interval_; }
283
  UsePosition* first_pos() const { return first_pos_; }
284
  LiveRange* parent() const { return parent_; }
285
  LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; }
286
  LiveRange* next() const { return next_; }
287
  bool IsChild() const { return parent() != NULL; }
288
  int id() const { return id_; }
289
  bool IsFixed() const { return id_ < 0; }
290
  bool IsEmpty() const { return first_interval() == NULL; }
291
  LOperand* CreateAssignedOperand(Zone* zone);
292
  int assigned_register() const { return assigned_register_; }
293
  int spill_start_index() const { return spill_start_index_; }
294
  void set_assigned_register(int reg, Zone* zone);
295
  void MakeSpilled(Zone* zone);
296

    
297
  // Returns use position in this live range that follows both start
298
  // and last processed use position.
299
  // Modifies internal state of live range!
300
  UsePosition* NextUsePosition(LifetimePosition start);
301

    
302
  // Returns use position for which register is required in this live
303
  // range and which follows both start and last processed use position
304
  // Modifies internal state of live range!
305
  UsePosition* NextRegisterPosition(LifetimePosition start);
306

    
307
  // Returns use position for which register is beneficial in this live
308
  // range and which follows both start and last processed use position
309
  // Modifies internal state of live range!
310
  UsePosition* NextUsePositionRegisterIsBeneficial(LifetimePosition start);
311

    
312
  // Returns use position for which register is beneficial in this live
313
  // range and which precedes start.
314
  UsePosition* PreviousUsePositionRegisterIsBeneficial(LifetimePosition start);
315

    
316
  // Can this live range be spilled at this position.
317
  bool CanBeSpilled(LifetimePosition pos);
318

    
319
  // Split this live range at the given position which must follow the start of
320
  // the range.
321
  // All uses following the given position will be moved from this
322
  // live range to the result live range.
323
  void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone);
324

    
325
  RegisterKind Kind() const { return kind_; }
326
  bool HasRegisterAssigned() const {
327
    return assigned_register_ != kInvalidAssignment;
328
  }
329
  bool IsSpilled() const { return spilled_; }
330

    
331
  LOperand* current_hint_operand() const {
332
    ASSERT(current_hint_operand_ == FirstHint());
333
    return current_hint_operand_;
334
  }
335
  LOperand* FirstHint() const {
336
    UsePosition* pos = first_pos_;
337
    while (pos != NULL && !pos->HasHint()) pos = pos->next();
338
    if (pos != NULL) return pos->hint();
339
    return NULL;
340
  }
341

    
342
  LifetimePosition Start() const {
343
    ASSERT(!IsEmpty());
344
    return first_interval()->start();
345
  }
346

    
347
  LifetimePosition End() const {
348
    ASSERT(!IsEmpty());
349
    return last_interval_->end();
350
  }
351

    
352
  bool HasAllocatedSpillOperand() const;
353
  LOperand* GetSpillOperand() const { return spill_operand_; }
354
  void SetSpillOperand(LOperand* operand);
355

    
356
  void SetSpillStartIndex(int start) {
357
    spill_start_index_ = Min(start, spill_start_index_);
358
  }
359

    
360
  bool ShouldBeAllocatedBefore(const LiveRange* other) const;
361
  bool CanCover(LifetimePosition position) const;
362
  bool Covers(LifetimePosition position);
363
  LifetimePosition FirstIntersection(LiveRange* other);
364

    
365
  // Add a new interval or a new use position to this live range.
366
  void EnsureInterval(LifetimePosition start,
367
                      LifetimePosition end,
368
                      Zone* zone);
369
  void AddUseInterval(LifetimePosition start,
370
                      LifetimePosition end,
371
                      Zone* zone);
372
  void AddUsePosition(LifetimePosition pos,
373
                      LOperand* operand,
374
                      LOperand* hint,
375
                      Zone* zone);
376

    
377
  // Shorten the most recently added interval by setting a new start.
378
  void ShortenTo(LifetimePosition start);
379

    
380
#ifdef DEBUG
381
  // True if target overlaps an existing interval.
382
  bool HasOverlap(UseInterval* target) const;
383
  void Verify() const;
384
#endif
385

    
386
 private:
387
  void ConvertOperands(Zone* zone);
388
  UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
389
  void AdvanceLastProcessedMarker(UseInterval* to_start_of,
390
                                  LifetimePosition but_not_past) const;
391

    
392
  int id_;
393
  bool spilled_;
394
  RegisterKind kind_;
395
  int assigned_register_;
396
  UseInterval* last_interval_;
397
  UseInterval* first_interval_;
398
  UsePosition* first_pos_;
399
  LiveRange* parent_;
400
  LiveRange* next_;
401
  // This is used as a cache, it doesn't affect correctness.
402
  mutable UseInterval* current_interval_;
403
  UsePosition* last_processed_use_;
404
  // This is used as a cache, it's invalid outside of BuildLiveRanges.
405
  LOperand* current_hint_operand_;
406
  LOperand* spill_operand_;
407
  int spill_start_index_;
408

    
409
  friend class LAllocator;  // Assigns to kind_.
410
};
411

    
412

    
413
class LAllocator BASE_EMBEDDED {
414
 public:
415
  LAllocator(int first_virtual_register, HGraph* graph);
416

    
417
  static void TraceAlloc(const char* msg, ...);
418

    
419
  // Checks whether the value of a given virtual register is tagged.
420
  bool HasTaggedValue(int virtual_register) const;
421

    
422
  // Returns the register kind required by the given virtual register.
423
  RegisterKind RequiredRegisterKind(int virtual_register) const;
424

    
425
  bool Allocate(LChunk* chunk);
426

    
427
  const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
428
  const Vector<LiveRange*>* fixed_live_ranges() const {
429
    return &fixed_live_ranges_;
430
  }
431
  const Vector<LiveRange*>* fixed_double_live_ranges() const {
432
    return &fixed_double_live_ranges_;
433
  }
434

    
435
  LPlatformChunk* chunk() const { return chunk_; }
436
  HGraph* graph() const { return graph_; }
437
  Isolate* isolate() const { return graph_->isolate(); }
438
  Zone* zone() { return &zone_; }
439

    
440
  int GetVirtualRegister() {
441
    if (next_virtual_register_ >= LUnallocated::kMaxVirtualRegisters) {
442
      allocation_ok_ = false;
443
      // Maintain the invariant that we return something below the maximum.
444
      return 0;
445
    }
446
    return next_virtual_register_++;
447
  }
448

    
449
  bool AllocationOk() { return allocation_ok_; }
450

    
451
  void MarkAsOsrEntry() {
452
    // There can be only one.
453
    ASSERT(!has_osr_entry_);
454
    // Simply set a flag to find and process instruction later.
455
    has_osr_entry_ = true;
456
  }
457

    
458
#ifdef DEBUG
459
  void Verify() const;
460
#endif
461

    
462
  BitVector* assigned_registers() {
463
    return assigned_registers_;
464
  }
465
  BitVector* assigned_double_registers() {
466
    return assigned_double_registers_;
467
  }
468

    
469
 private:
470
  void MeetRegisterConstraints();
471
  void ResolvePhis();
472
  void BuildLiveRanges();
473
  void AllocateGeneralRegisters();
474
  void AllocateDoubleRegisters();
475
  void ConnectRanges();
476
  void ResolveControlFlow();
477
  void PopulatePointerMaps();
478
  void AllocateRegisters();
479
  bool CanEagerlyResolveControlFlow(HBasicBlock* block) const;
480
  inline bool SafePointsAreInOrder() const;
481

    
482
  // Liveness analysis support.
483
  void InitializeLivenessAnalysis();
484
  BitVector* ComputeLiveOut(HBasicBlock* block);
485
  void AddInitialIntervals(HBasicBlock* block, BitVector* live_out);
486
  void ProcessInstructions(HBasicBlock* block, BitVector* live);
487
  void MeetRegisterConstraints(HBasicBlock* block);
488
  void MeetConstraintsBetween(LInstruction* first,
489
                              LInstruction* second,
490
                              int gap_index);
491
  void ResolvePhis(HBasicBlock* block);
492

    
493
  // Helper methods for building intervals.
494
  LOperand* AllocateFixed(LUnallocated* operand, int pos, bool is_tagged);
495
  LiveRange* LiveRangeFor(LOperand* operand);
496
  void Define(LifetimePosition position, LOperand* operand, LOperand* hint);
497
  void Use(LifetimePosition block_start,
498
           LifetimePosition position,
499
           LOperand* operand,
500
           LOperand* hint);
501
  void AddConstraintsGapMove(int index, LOperand* from, LOperand* to);
502

    
503
  // Helper methods for updating the life range lists.
504
  void AddToActive(LiveRange* range);
505
  void AddToInactive(LiveRange* range);
506
  void AddToUnhandledSorted(LiveRange* range);
507
  void AddToUnhandledUnsorted(LiveRange* range);
508
  void SortUnhandled();
509
  bool UnhandledIsSorted();
510
  void ActiveToHandled(LiveRange* range);
511
  void ActiveToInactive(LiveRange* range);
512
  void InactiveToHandled(LiveRange* range);
513
  void InactiveToActive(LiveRange* range);
514
  void FreeSpillSlot(LiveRange* range);
515
  LOperand* TryReuseSpillSlot(LiveRange* range);
516

    
517
  // Helper methods for allocating registers.
518
  bool TryAllocateFreeReg(LiveRange* range);
519
  void AllocateBlockedReg(LiveRange* range);
520

    
521
  // Live range splitting helpers.
522

    
523
  // Split the given range at the given position.
524
  // If range starts at or after the given position then the
525
  // original range is returned.
526
  // Otherwise returns the live range that starts at pos and contains
527
  // all uses from the original range that follow pos. Uses at pos will
528
  // still be owned by the original range after splitting.
529
  LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
530

    
531
  // Split the given range in a position from the interval [start, end].
532
  LiveRange* SplitBetween(LiveRange* range,
533
                          LifetimePosition start,
534
                          LifetimePosition end);
535

    
536
  // Find a lifetime position in the interval [start, end] which
537
  // is optimal for splitting: it is either header of the outermost
538
  // loop covered by this interval or the latest possible position.
539
  LifetimePosition FindOptimalSplitPos(LifetimePosition start,
540
                                       LifetimePosition end);
541

    
542
  // Spill the given life range after position pos.
543
  void SpillAfter(LiveRange* range, LifetimePosition pos);
544

    
545
  // Spill the given life range after position [start] and up to position [end].
546
  void SpillBetween(LiveRange* range,
547
                    LifetimePosition start,
548
                    LifetimePosition end);
549

    
550
  // Spill the given life range after position [start] and up to position [end].
551
  // Range is guaranteed to be spilled at least until position [until].
552
  void SpillBetweenUntil(LiveRange* range,
553
                         LifetimePosition start,
554
                         LifetimePosition until,
555
                         LifetimePosition end);
556

    
557
  void SplitAndSpillIntersecting(LiveRange* range);
558

    
559
  // If we are trying to spill a range inside the loop try to
560
  // hoist spill position out to the point just before the loop.
561
  LifetimePosition FindOptimalSpillingPos(LiveRange* range,
562
                                          LifetimePosition pos);
563

    
564
  void Spill(LiveRange* range);
565
  bool IsBlockBoundary(LifetimePosition pos);
566

    
567
  // Helper methods for resolving control flow.
568
  void ResolveControlFlow(LiveRange* range,
569
                          HBasicBlock* block,
570
                          HBasicBlock* pred);
571

    
572
  inline void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
573

    
574
  // Return parallel move that should be used to connect ranges split at the
575
  // given position.
576
  LParallelMove* GetConnectingParallelMove(LifetimePosition pos);
577

    
578
  // Return the block which contains give lifetime position.
579
  HBasicBlock* GetBlock(LifetimePosition pos);
580

    
581
  // Helper methods for the fixed registers.
582
  int RegisterCount() const;
583
  static int FixedLiveRangeID(int index) { return -index - 1; }
584
  static int FixedDoubleLiveRangeID(int index);
585
  LiveRange* FixedLiveRangeFor(int index);
586
  LiveRange* FixedDoubleLiveRangeFor(int index);
587
  LiveRange* LiveRangeFor(int index);
588
  HPhi* LookupPhi(LOperand* operand) const;
589
  LGap* GetLastGap(HBasicBlock* block);
590

    
591
  const char* RegisterName(int allocation_index);
592

    
593
  inline bool IsGapAt(int index);
594

    
595
  inline LInstruction* InstructionAt(int index);
596

    
597
  inline LGap* GapAt(int index);
598

    
599
  Zone zone_;
600

    
601
  LPlatformChunk* chunk_;
602

    
603
  // During liveness analysis keep a mapping from block id to live_in sets
604
  // for blocks already analyzed.
605
  ZoneList<BitVector*> live_in_sets_;
606

    
607
  // Liveness analysis results.
608
  ZoneList<LiveRange*> live_ranges_;
609

    
610
  // Lists of live ranges
611
  EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters>
612
      fixed_live_ranges_;
613
  EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters>
614
      fixed_double_live_ranges_;
615
  ZoneList<LiveRange*> unhandled_live_ranges_;
616
  ZoneList<LiveRange*> active_live_ranges_;
617
  ZoneList<LiveRange*> inactive_live_ranges_;
618
  ZoneList<LiveRange*> reusable_slots_;
619

    
620
  // Next virtual register number to be assigned to temporaries.
621
  int next_virtual_register_;
622
  int first_artificial_register_;
623
  GrowableBitVector double_artificial_registers_;
624

    
625
  RegisterKind mode_;
626
  int num_registers_;
627

    
628
  BitVector* assigned_registers_;
629
  BitVector* assigned_double_registers_;
630

    
631
  HGraph* graph_;
632

    
633
  bool has_osr_entry_;
634

    
635
  // Indicates success or failure during register allocation.
636
  bool allocation_ok_;
637

    
638
#ifdef DEBUG
639
  LifetimePosition allocation_finger_;
640
#endif
641

    
642
  DISALLOW_COPY_AND_ASSIGN(LAllocator);
643
};
644

    
645

    
646
class LAllocatorPhase : public CompilationPhase {
647
 public:
648
  LAllocatorPhase(const char* name, LAllocator* allocator);
649
  ~LAllocatorPhase();
650

    
651
 private:
652
  LAllocator* allocator_;
653
  unsigned allocator_zone_start_allocation_size_;
654

    
655
  DISALLOW_COPY_AND_ASSIGN(LAllocatorPhase);
656
};
657

    
658

    
659
} }  // namespace v8::internal
660

    
661
#endif  // V8_LITHIUM_ALLOCATOR_H_