28 #ifndef V8_LITHIUM_ALLOCATOR_H_
29 #define V8_LITHIUM_ALLOCATOR_H_
54 class LConstantOperand;
83 return value_ / kStep;
89 return (value_ & (kStep - 1)) == 0;
137 static const int kStep = 2;
163 inline explicit TempIterator(LInstruction* instr);
165 inline LOperand* Current();
166 inline void Advance();
169 inline void SkipUninteresting();
170 LInstruction* instr_;
179 inline explicit InputIterator(LInstruction* instr);
181 inline LOperand* Current();
182 inline void Advance();
185 inline void SkipUninteresting();
186 LInstruction* instr_;
194 inline explicit UseIterator(LInstruction* instr);
196 inline LOperand* Current();
197 inline void Advance();
200 InputIterator input_iterator_;
201 DeepIterator env_iterator_;
209 : start_(start), end_(end), next_(
NULL) {
237 LifetimePosition start_;
238 LifetimePosition end_;
266 LifetimePosition pos_;
269 bool register_beneficial_;
288 int id()
const {
return id_; }
332 if (pos !=
NULL)
return pos->
hint();
343 return last_interval_->
end();
351 spill_start_index_ =
Min(start, spill_start_index_);
380 void ConvertOperands(
Zone* zone);
382 void AdvanceLastProcessedMarker(
UseInterval* to_start_of,
388 int assigned_register_;
398 int spill_start_index_;
407 if (!InBitsRange(value))
return false;
408 return bits_->Contains(value);
412 EnsureCapacity(value, zone);
417 static const int kInitialLength = 1024;
419 bool InBitsRange(
int value)
const {
420 return bits_ !=
NULL && bits_->length() > value;
423 void EnsureCapacity(
int value, Zone* zone) {
424 if (InBitsRange(value))
return;
425 int new_length = bits_ ==
NULL ? kInitialLength : bits_->length();
426 while (new_length <= value) new_length *= 2;
427 BitVector* new_bits =
new(zone) BitVector(new_length, zone);
428 if (bits_ !=
NULL) new_bits->CopyFrom(*bits_);
438 LAllocator(
int first_virtual_register, HGraph* graph);
440 static void TraceAlloc(
const char* msg, ...);
443 bool HasTaggedValue(
int virtual_register)
const;
446 RegisterKind RequiredRegisterKind(
int virtual_register)
const;
448 bool Allocate(LChunk* chunk);
452 return &fixed_live_ranges_;
455 return &fixed_double_live_ranges_;
464 allocation_ok_ =
false;
466 return next_virtual_register_++;
475 has_osr_entry_ =
true;
483 void MeetRegisterConstraints();
485 void BuildLiveRanges();
486 void AllocateGeneralRegisters();
487 void AllocateDoubleRegisters();
488 void ConnectRanges();
489 void ResolveControlFlow();
490 void PopulatePointerMaps();
491 void ProcessOsrEntry();
492 void AllocateRegisters();
493 bool CanEagerlyResolveControlFlow(
HBasicBlock* block)
const;
494 inline bool SafePointsAreInOrder()
const;
497 void InitializeLivenessAnalysis();
520 void AddToUnhandledSorted(
LiveRange* range);
521 void AddToUnhandledUnsorted(
LiveRange* range);
522 void SortUnhandled();
523 bool UnhandledIsSorted();
526 void InactiveToHandled(
LiveRange* range);
532 bool TryAllocateFreeReg(
LiveRange* range);
533 void AllocateBlockedReg(
LiveRange* range);
564 void SplitAndSpillIntersecting(
LiveRange* range);
570 void ResolveControlFlow(
LiveRange* range,
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);
591 const char* RegisterName(
int allocation_index);
593 inline bool IsGapAt(
int index);
595 inline LInstruction* InstructionAt(
int index);
597 inline LGap* GapAt(
int index);
601 LPlatformChunk* chunk_;
605 ZoneList<BitVector*> live_in_sets_;
608 ZoneList<LiveRange*> live_ranges_;
611 EmbeddedVector<LiveRange*, Register::kNumAllocatableRegisters>
613 EmbeddedVector<LiveRange*, DoubleRegister::kNumAllocatableRegisters>
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_;
621 int next_virtual_register_;
622 int first_artificial_register_;
623 GrowableBitVector double_artificial_registers_;
641 #endif // V8_LITHIUM_ALLOCATOR_H_
LOperand * operand() const
UseInterval * next() const
LifetimePosition FirstIntersection(LiveRange *other)
bool HasAllocatedSpillOperand() const
void MakeSpilled(Zone *zone)
void Add(int value, Zone *zone)
int spill_start_index() const
UsePosition * AddUsePosition(LifetimePosition pos, LOperand *operand, Zone *zone)
static LifetimePosition MaxPosition()
LiveRange(int id, Zone *zone)
LiveRange * parent() const
static LifetimePosition Invalid()
void ShortenTo(LifetimePosition start)
bool ShouldBeAllocatedBefore(const LiveRange *other) const
UsePosition * NextUsePosition(LifetimePosition start)
static LifetimePosition FromInstructionIndex(int index)
bool CanCover(LifetimePosition position) const
void SetSpillStartIndex(int start)
#define ASSERT(condition)
LifetimePosition InstructionStart() const
LifetimePosition NextInstruction() const
LifetimePosition pos() const
bool Covers(LifetimePosition position)
LOperand * CreateAssignedOperand(Zone *zone)
static const int kMaxVirtualRegisters
LifetimePosition End() const
bool CanBeSpilled(LifetimePosition pos)
bool HasRegisterAssigned() const
void SplitAt(LifetimePosition position, LiveRange *result, Zone *zone)
LifetimePosition end() const
void SetSpillOperand(LOperand *operand)
UsePosition * NextUsePositionRegisterIsBeneficial(LifetimePosition start)
const Vector< LiveRange * > * fixed_double_live_ranges() const
UseInterval * first_interval() const
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
void SplitAt(LifetimePosition pos, Zone *zone)
LifetimePosition PrevInstruction() const
bool Contains(LifetimePosition point) const
const ZoneList< LiveRange * > * live_ranges() const
LOperand * FirstHint() const
LifetimePosition start() const
LifetimePosition Start() const
UseInterval(LifetimePosition start, LifetimePosition end)
void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone *zone)
UsePosition(LifetimePosition pos, LOperand *operand)
bool RequiresRegister() const
int assigned_register() const
UsePosition * first_pos() const
#define IS_POWER_OF_TWO(x)
UsePosition * NextRegisterPosition(LifetimePosition start)
void set_hint(LOperand *hint)
UsePosition * FirstPosWithHint() const
void set_assigned_register(int reg, RegisterKind register_kind, Zone *zone)
LifetimePosition Intersect(const UseInterval *other) const
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
bool IsInstructionStart() const
UsePosition * next() const
void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone *zone)
bool Contains(int value) const
LOperand * GetSpillOperand() const
int InstructionIndex() const
LPlatformChunk * chunk() const
const Vector< LiveRange * > * fixed_live_ranges() const
static const int kInvalidAssignment
LifetimePosition InstructionEnd() const
bool RegisterIsBeneficial() const