Remove instruction summaries.

Instead of constructing a temporary container for all LOperands of each
instruction, the register works directly on the LIR instructions that
 provide an abstract interface for input/output/temp operands.

This saves allocation of zone memory and speeds up LIR construction,
but makes iterating over all uses in the register allocator slightly
more expensive because environment uses are stored in a linked list of
environments. We can fix this by using a flat representation of LOperands.


Review URL: http://codereview.chromium.org/6352006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6638 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f1acd129
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "lithium-allocator-inl.h"
#include "arm/lithium-arm.h" #include "arm/lithium-arm.h"
#include "arm/lithium-codegen-arm.h" #include "arm/lithium-codegen-arm.h"
...@@ -56,6 +57,31 @@ void LOsrEntry::MarkSpilledRegister(int allocation_index, ...@@ -56,6 +57,31 @@ void LOsrEntry::MarkSpilledRegister(int allocation_index,
} }
#ifdef DEBUG
void LInstruction::VerifyCall() {
// Call instructions can use only fixed registers as
// temporaries and outputs because all registers
// are blocked by the calling convention.
// Inputs can use either fixed register or have a short lifetime (be
// used at start of the instruction).
ASSERT(Output() == NULL ||
LUnallocated::cast(Output())->HasFixedPolicy() ||
!LUnallocated::cast(Output())->HasRegisterPolicy());
for (UseIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
LUnallocated::cast(operand)->IsUsedAtStart() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
}
for (TempIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
}
}
#endif
void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
LOperand* spill_operand) { LOperand* spill_operand) {
ASSERT(spill_operand->IsDoubleStackSlot()); ASSERT(spill_operand->IsDoubleStackSlot());
...@@ -66,9 +92,8 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, ...@@ -66,9 +92,8 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
void LInstruction::PrintTo(StringStream* stream) { void LInstruction::PrintTo(StringStream* stream) {
stream->Add("%s ", this->Mnemonic()); stream->Add("%s ", this->Mnemonic());
if (HasResult()) {
PrintOutputOperandTo(stream); PrintOutputOperandTo(stream);
}
PrintDataTo(stream); PrintDataTo(stream);
...@@ -401,7 +426,7 @@ void LChunk::MarkEmptyBlocks() { ...@@ -401,7 +426,7 @@ void LChunk::MarkEmptyBlocks() {
} }
int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LGap* gap = new LGap(block); LGap* gap = new LGap(block);
int index = -1; int index = -1;
if (instr->IsControl()) { if (instr->IsControl()) {
...@@ -417,7 +442,6 @@ int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { ...@@ -417,7 +442,6 @@ int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
pointer_maps_.Add(instr->pointer_map()); pointer_maps_.Add(instr->pointer_map());
instr->pointer_map()->set_lithium_position(index); instr->pointer_map()->set_lithium_position(index);
} }
return index;
} }
...@@ -683,7 +707,10 @@ void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { ...@@ -683,7 +707,10 @@ void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
HInstruction* hinstr, HInstruction* hinstr,
CanDeoptimize can_deoptimize) { CanDeoptimize can_deoptimize) {
allocator_->MarkAsCall(); #ifdef DEBUG
instr->VerifyCall();
#endif
instr->MarkAsCall();
instr = AssignPointerMap(instr); instr = AssignPointerMap(instr);
if (hinstr->HasSideEffects()) { if (hinstr->HasSideEffects()) {
...@@ -708,7 +735,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, ...@@ -708,7 +735,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
allocator_->MarkAsSaveDoubles(); instr->MarkAsSaveDoubles();
return instr; return instr;
} }
...@@ -908,7 +935,6 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { ...@@ -908,7 +935,6 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
void LChunkBuilder::VisitInstruction(HInstruction* current) { void LChunkBuilder::VisitInstruction(HInstruction* current) {
HInstruction* old_current = current_instruction_; HInstruction* old_current = current_instruction_;
current_instruction_ = current; current_instruction_ = current;
allocator_->BeginInstruction();
if (current->has_position()) position_ = current->position(); if (current->has_position()) position_ = current->position();
LInstruction* instr = current->CompileToLithium(this); LInstruction* instr = current->CompileToLithium(this);
...@@ -931,11 +957,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { ...@@ -931,11 +957,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
instr->set_hydrogen_value(current); instr->set_hydrogen_value(current);
} }
int index = chunk_->AddInstruction(instr, current_block_); chunk_->AddInstruction(instr, current_block_);
allocator_->SummarizeInstruction(index);
} else {
// This instruction should be omitted.
allocator_->OmitInstruction();
} }
current_instruction_ = old_current; current_instruction_ = old_current;
} }
......
...@@ -181,7 +181,10 @@ class LCodeGen; ...@@ -181,7 +181,10 @@ class LCodeGen;
class LInstruction: public ZoneObject { class LInstruction: public ZoneObject {
public: public:
LInstruction() LInstruction()
: hydrogen_value_(NULL) { } : environment_(NULL),
hydrogen_value_(NULL),
is_call_(false),
is_save_doubles_(false) { }
virtual ~LInstruction() { } virtual ~LInstruction() { }
virtual void CompileToNative(LCodeGen* generator) = 0; virtual void CompileToNative(LCodeGen* generator) = 0;
...@@ -198,16 +201,14 @@ class LInstruction: public ZoneObject { ...@@ -198,16 +201,14 @@ class LInstruction: public ZoneObject {
virtual bool IsControl() const { return false; } virtual bool IsControl() const { return false; }
virtual void SetBranchTargets(int true_block_id, int false_block_id) { } virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
void set_environment(LEnvironment* env) { environment_.set(env); } void set_environment(LEnvironment* env) { environment_ = env; }
LEnvironment* environment() const { return environment_.get(); } LEnvironment* environment() const { return environment_; }
bool HasEnvironment() const { return environment_.is_set(); } bool HasEnvironment() const { return environment_ != NULL; }
void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
LPointerMap* pointer_map() const { return pointer_map_.get(); } LPointerMap* pointer_map() const { return pointer_map_.get(); }
bool HasPointerMap() const { return pointer_map_.is_set(); } bool HasPointerMap() const { return pointer_map_.is_set(); }
virtual bool HasResult() const = 0;
void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
HValue* hydrogen_value() const { return hydrogen_value_; } HValue* hydrogen_value() const { return hydrogen_value_; }
...@@ -221,11 +222,31 @@ class LInstruction: public ZoneObject { ...@@ -221,11 +222,31 @@ class LInstruction: public ZoneObject {
return deoptimization_environment_.is_set(); return deoptimization_environment_.is_set();
} }
void MarkAsCall() { is_call_ = true; }
void MarkAsSaveDoubles() { is_save_doubles_ = true; }
// Interface to the register allocator and iterators.
bool IsMarkedAsCall() const { return is_call_; }
bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; }
virtual bool HasResult() const = 0;
virtual LOperand* result() = 0;
virtual int InputCount() = 0;
virtual LOperand* InputAt(int i) = 0;
virtual int TempCount() = 0;
virtual LOperand* TempAt(int i) = 0;
LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; }
private: private:
SetOncePointer<LEnvironment> environment_; LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_; SetOncePointer<LPointerMap> pointer_map_;
HValue* hydrogen_value_; HValue* hydrogen_value_;
SetOncePointer<LEnvironment> deoptimization_environment_; SetOncePointer<LEnvironment> deoptimization_environment_;
bool is_call_;
bool is_save_doubles_;
}; };
...@@ -252,6 +273,11 @@ class OperandContainer<ElementType, 0> { ...@@ -252,6 +273,11 @@ class OperandContainer<ElementType, 0> {
public: public:
int length() { return 0; } int length() { return 0; }
void PrintOperandsTo(StringStream* stream) { } void PrintOperandsTo(StringStream* stream) { }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
return t;
}
}; };
...@@ -1734,7 +1760,7 @@ class LChunk: public ZoneObject { ...@@ -1734,7 +1760,7 @@ class LChunk: public ZoneObject {
public: public:
explicit LChunk(HGraph* graph); explicit LChunk(HGraph* graph);
int AddInstruction(LInstruction* instruction, HBasicBlock* block); void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant); LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const; Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const; Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#if defined(V8_TARGET_ARCH_IA32) #if defined(V8_TARGET_ARCH_IA32)
#include "lithium-allocator-inl.h"
#include "ia32/lithium-ia32.h" #include "ia32/lithium-ia32.h"
#include "ia32/lithium-codegen-ia32.h" #include "ia32/lithium-codegen-ia32.h"
...@@ -68,11 +69,35 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, ...@@ -68,11 +69,35 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
} }
#ifdef DEBUG
void LInstruction::VerifyCall() {
// Call instructions can use only fixed registers as
// temporaries and outputs because all registers
// are blocked by the calling convention.
// Inputs can use either fixed register or have a short lifetime (be
// used at start of the instruction).
ASSERT(Output() == NULL ||
LUnallocated::cast(Output())->HasFixedPolicy() ||
!LUnallocated::cast(Output())->HasRegisterPolicy());
for (UseIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
LUnallocated::cast(operand)->IsUsedAtStart() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
}
for (TempIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
}
}
#endif
void LInstruction::PrintTo(StringStream* stream) { void LInstruction::PrintTo(StringStream* stream) {
stream->Add("%s ", this->Mnemonic()); stream->Add("%s ", this->Mnemonic());
if (HasResult()) {
PrintOutputOperandTo(stream); PrintOutputOperandTo(stream);
}
PrintDataTo(stream); PrintDataTo(stream);
...@@ -399,7 +424,7 @@ void LStoreKeyed::PrintDataTo(StringStream* stream) { ...@@ -399,7 +424,7 @@ void LStoreKeyed::PrintDataTo(StringStream* stream) {
} }
int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LGap* gap = new LGap(block); LGap* gap = new LGap(block);
int index = -1; int index = -1;
if (instr->IsControl()) { if (instr->IsControl()) {
...@@ -415,7 +440,6 @@ int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { ...@@ -415,7 +440,6 @@ int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
pointer_maps_.Add(instr->pointer_map()); pointer_maps_.Add(instr->pointer_map());
instr->pointer_map()->set_lithium_position(index); instr->pointer_map()->set_lithium_position(index);
} }
return index;
} }
...@@ -683,7 +707,10 @@ void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { ...@@ -683,7 +707,10 @@ void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
HInstruction* hinstr, HInstruction* hinstr,
CanDeoptimize can_deoptimize) { CanDeoptimize can_deoptimize) {
allocator_->MarkAsCall(); #ifdef DEBUG
instr->VerifyCall();
#endif
instr->MarkAsCall();
instr = AssignPointerMap(instr); instr = AssignPointerMap(instr);
if (hinstr->HasSideEffects()) { if (hinstr->HasSideEffects()) {
...@@ -708,7 +735,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, ...@@ -708,7 +735,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
allocator_->MarkAsSaveDoubles(); instr->MarkAsSaveDoubles();
return instr; return instr;
} }
...@@ -917,7 +944,6 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { ...@@ -917,7 +944,6 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
void LChunkBuilder::VisitInstruction(HInstruction* current) { void LChunkBuilder::VisitInstruction(HInstruction* current) {
HInstruction* old_current = current_instruction_; HInstruction* old_current = current_instruction_;
current_instruction_ = current; current_instruction_ = current;
allocator_->BeginInstruction();
if (current->has_position()) position_ = current->position(); if (current->has_position()) position_ = current->position();
LInstruction* instr = current->CompileToLithium(this); LInstruction* instr = current->CompileToLithium(this);
...@@ -940,11 +966,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { ...@@ -940,11 +966,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
instr->set_hydrogen_value(current); instr->set_hydrogen_value(current);
} }
int index = chunk_->AddInstruction(instr, current_block_); chunk_->AddInstruction(instr, current_block_);
allocator_->SummarizeInstruction(index);
} else {
// This instruction should be omitted.
allocator_->OmitInstruction();
} }
current_instruction_ = old_current; current_instruction_ = old_current;
} }
......
...@@ -182,7 +182,10 @@ class LCodeGen; ...@@ -182,7 +182,10 @@ class LCodeGen;
class LInstruction: public ZoneObject { class LInstruction: public ZoneObject {
public: public:
LInstruction() LInstruction()
: hydrogen_value_(NULL) { } : environment_(NULL),
hydrogen_value_(NULL),
is_call_(false),
is_save_doubles_(false) { }
virtual ~LInstruction() { } virtual ~LInstruction() { }
virtual void CompileToNative(LCodeGen* generator) = 0; virtual void CompileToNative(LCodeGen* generator) = 0;
...@@ -199,15 +202,14 @@ class LInstruction: public ZoneObject { ...@@ -199,15 +202,14 @@ class LInstruction: public ZoneObject {
virtual bool IsControl() const { return false; } virtual bool IsControl() const { return false; }
virtual void SetBranchTargets(int true_block_id, int false_block_id) { } virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
void set_environment(LEnvironment* env) { environment_.set(env); } void set_environment(LEnvironment* env) { environment_ = env; }
LEnvironment* environment() const { return environment_.get(); } LEnvironment* environment() const { return environment_; }
bool HasEnvironment() const { return environment_.is_set(); } bool HasEnvironment() const { return environment_ != NULL; }
void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
LPointerMap* pointer_map() const { return pointer_map_.get(); } LPointerMap* pointer_map() const { return pointer_map_.get(); }
bool HasPointerMap() const { return pointer_map_.is_set(); } bool HasPointerMap() const { return pointer_map_.is_set(); }
virtual bool HasResult() const = 0;
void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
HValue* hydrogen_value() const { return hydrogen_value_; } HValue* hydrogen_value() const { return hydrogen_value_; }
...@@ -222,11 +224,35 @@ class LInstruction: public ZoneObject { ...@@ -222,11 +224,35 @@ class LInstruction: public ZoneObject {
return deoptimization_environment_.is_set(); return deoptimization_environment_.is_set();
} }
void MarkAsCall() { is_call_ = true; }
void MarkAsSaveDoubles() { is_save_doubles_ = true; }
// Interface to the register allocator and iterators.
bool IsMarkedAsCall() const { return is_call_; }
bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; }
virtual bool HasResult() const = 0;
virtual LOperand* result() = 0;
virtual int InputCount() = 0;
virtual LOperand* InputAt(int i) = 0;
virtual int TempCount() = 0;
virtual LOperand* TempAt(int i) = 0;
LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; }
#ifdef DEBUG
void VerifyCall();
#endif
private: private:
SetOncePointer<LEnvironment> environment_; LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_; SetOncePointer<LPointerMap> pointer_map_;
HValue* hydrogen_value_; HValue* hydrogen_value_;
SetOncePointer<LEnvironment> deoptimization_environment_; SetOncePointer<LEnvironment> deoptimization_environment_;
bool is_call_;
bool is_save_doubles_;
}; };
...@@ -253,6 +279,11 @@ class OperandContainer<ElementType, 0> { ...@@ -253,6 +279,11 @@ class OperandContainer<ElementType, 0> {
public: public:
int length() { return 0; } int length() { return 0; }
void PrintOperandsTo(StringStream* stream) { } void PrintOperandsTo(StringStream* stream) { }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
return t;
}
}; };
...@@ -1760,7 +1791,7 @@ class LChunk: public ZoneObject { ...@@ -1760,7 +1791,7 @@ class LChunk: public ZoneObject {
pointer_maps_(8), pointer_maps_(8),
inlined_closures_(1) { } inlined_closures_(1) { }
int AddInstruction(LInstruction* instruction, HBasicBlock* block); void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant); LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const; Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const; Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
......
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_LITHIUM_ALLOCATOR_INL_H_
#define V8_LITHIUM_ALLOCATOR_INL_H_
#include "lithium-allocator.h"
#if V8_TARGET_ARCH_IA32
#include "ia32/lithium-ia32.h"
#elif V8_TARGET_ARCH_X64
#include "x64/lithium-x64.h"
#elif V8_TARGET_ARCH_ARM
#include "arm/lithium-arm.h"
#else
#error "Unknown architecture."
#endif
namespace v8 {
namespace internal {
bool LAllocator::IsGapAt(int index) { return chunk_->IsGapAt(index); }
LInstruction* LAllocator::InstructionAt(int index) {
return chunk_->instructions()->at(index);
}
LGap* LAllocator::GapAt(int index) {
return chunk_->GetGapAt(index);
}
TempIterator::TempIterator(LInstruction* instr)
: instr_(instr),
limit_(instr->TempCount()),
current_(0) {
current_ = AdvanceToNext(0);
}
bool TempIterator::HasNext() { return current_ < limit_; }
LOperand* TempIterator::Next() {
ASSERT(HasNext());
return instr_->TempAt(current_);
}
int TempIterator::AdvanceToNext(int start) {
while (start < limit_ && instr_->TempAt(start) == NULL) start++;
return start;
}
void TempIterator::Advance() {
current_ = AdvanceToNext(current_ + 1);
}
InputIterator::InputIterator(LInstruction* instr)
: instr_(instr),
limit_(instr->InputCount()),
current_(0) {
current_ = AdvanceToNext(0);
}
bool InputIterator::HasNext() { return current_ < limit_; }
LOperand* InputIterator::Next() {
ASSERT(HasNext());
return instr_->InputAt(current_);
}
void InputIterator::Advance() {
current_ = AdvanceToNext(current_ + 1);
}
int InputIterator::AdvanceToNext(int start) {
while (start < limit_ && instr_->InputAt(start)->IsConstantOperand()) start++;
return start;
}
UseIterator::UseIterator(LInstruction* instr)
: input_iterator_(instr), env_iterator_(instr->environment()) { }
bool UseIterator::HasNext() {
return input_iterator_.HasNext() || env_iterator_.HasNext();
}
LOperand* UseIterator::Next() {
ASSERT(HasNext());
return input_iterator_.HasNext()
? input_iterator_.Next()
: env_iterator_.Next();
}
void UseIterator::Advance() {
input_iterator_.HasNext()
? input_iterator_.Advance()
: env_iterator_.Advance();
}
} } // namespace v8::internal
#endif // V8_LITHIUM_ALLOCATOR_INL_H_
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "lithium-allocator.h" #include "lithium-allocator-inl.h"
#include "hydrogen.h" #include "hydrogen.h"
#include "string-stream.h" #include "string-stream.h"
...@@ -532,7 +532,7 @@ LifetimePosition LiveRange::FirstIntersection(LiveRange* other) { ...@@ -532,7 +532,7 @@ LifetimePosition LiveRange::FirstIntersection(LiveRange* other) {
void LAllocator::InitializeLivenessAnalysis() { void LAllocator::InitializeLivenessAnalysis() {
// Initialize the live_in sets for each block to NULL. // Initialize the live_in sets for each block to NULL.
int block_count = graph()->blocks()->length(); int block_count = graph_->blocks()->length();
live_in_sets_.Initialize(block_count); live_in_sets_.Initialize(block_count);
live_in_sets_.AddBlock(NULL, block_count); live_in_sets_.AddBlock(NULL, block_count);
} }
...@@ -613,7 +613,7 @@ LOperand* LAllocator::AllocateFixed(LUnallocated* operand, ...@@ -613,7 +613,7 @@ LOperand* LAllocator::AllocateFixed(LUnallocated* operand,
} }
if (is_tagged) { if (is_tagged) {
TraceAlloc("Fixed reg is tagged at %d\n", pos); TraceAlloc("Fixed reg is tagged at %d\n", pos);
LInstruction* instr = chunk_->instructions()->at(pos); LInstruction* instr = InstructionAt(pos);
if (instr->HasPointerMap()) { if (instr->HasPointerMap()) {
instr->pointer_map()->RecordPointer(operand); instr->pointer_map()->RecordPointer(operand);
} }
...@@ -668,17 +668,17 @@ LiveRange* LAllocator::LiveRangeFor(int index) { ...@@ -668,17 +668,17 @@ LiveRange* LAllocator::LiveRangeFor(int index) {
} }
LGap* LAllocator::GetLastGap(HBasicBlock* block) const { LGap* LAllocator::GetLastGap(HBasicBlock* block) {
int last_instruction = block->last_instruction_index(); int last_instruction = block->last_instruction_index();
int index = chunk_->NearestGapPos(last_instruction); int index = chunk_->NearestGapPos(last_instruction);
return chunk_->GetGapAt(index); return GapAt(index);
} }
HPhi* LAllocator::LookupPhi(LOperand* operand) const { HPhi* LAllocator::LookupPhi(LOperand* operand) const {
if (!operand->IsUnallocated()) return NULL; if (!operand->IsUnallocated()) return NULL;
int index = operand->VirtualRegister(); int index = operand->VirtualRegister();
HValue* instr = graph()->LookupValue(index); HValue* instr = graph_->LookupValue(index);
if (instr != NULL && instr->IsPhi()) { if (instr != NULL && instr->IsPhi()) {
return HPhi::cast(instr); return HPhi::cast(instr);
} }
...@@ -737,7 +737,7 @@ void LAllocator::Use(LifetimePosition block_start, ...@@ -737,7 +737,7 @@ void LAllocator::Use(LifetimePosition block_start,
void LAllocator::AddConstraintsGapMove(int index, void LAllocator::AddConstraintsGapMove(int index,
LOperand* from, LOperand* from,
LOperand* to) { LOperand* to) {
LGap* gap = chunk_->GetGapAt(index); LGap* gap = GapAt(index);
LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
if (from->IsUnallocated()) { if (from->IsUnallocated()) {
const ZoneList<LMoveOperands>* move_operands = move->move_operands(); const ZoneList<LMoveOperands>* move_operands = move->move_operands();
...@@ -760,24 +760,24 @@ void LAllocator::MeetRegisterConstraints(HBasicBlock* block) { ...@@ -760,24 +760,24 @@ void LAllocator::MeetRegisterConstraints(HBasicBlock* block) {
int start = block->first_instruction_index(); int start = block->first_instruction_index();
int end = block->last_instruction_index(); int end = block->last_instruction_index();
for (int i = start; i <= end; ++i) { for (int i = start; i <= end; ++i) {
if (chunk_->IsGapAt(i)) { if (IsGapAt(i)) {
InstructionSummary* summary = NULL; LInstruction* instr = NULL;
InstructionSummary* prev_summary = NULL; LInstruction* prev_instr = NULL;
if (i < end) summary = GetSummary(i + 1); if (i < end) instr = InstructionAt(i + 1);
if (i > start) prev_summary = GetSummary(i - 1); if (i > start) prev_instr = InstructionAt(i - 1);
MeetConstraintsBetween(prev_summary, summary, i); MeetConstraintsBetween(prev_instr, instr, i);
} }
} }
} }
void LAllocator::MeetConstraintsBetween(InstructionSummary* first, void LAllocator::MeetConstraintsBetween(LInstruction* first,
InstructionSummary* second, LInstruction* second,
int gap_index) { int gap_index) {
// Handle fixed temporaries. // Handle fixed temporaries.
if (first != NULL) { if (first != NULL) {
for (int i = 0; i < first->TempCount(); ++i) { for (TempIterator it(first); it.HasNext(); it.Advance()) {
LUnallocated* temp = LUnallocated::cast(first->TempAt(i)); LUnallocated* temp = LUnallocated::cast(it.Next());
if (temp->HasFixedPolicy()) { if (temp->HasFixedPolicy()) {
AllocateFixed(temp, gap_index - 1, false); AllocateFixed(temp, gap_index - 1, false);
} }
...@@ -810,7 +810,7 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first, ...@@ -810,7 +810,7 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first,
// and splitting of live ranges do not account for it. // and splitting of live ranges do not account for it.
// Thus it should be inserted to a lifetime position corresponding to // Thus it should be inserted to a lifetime position corresponding to
// the instruction end. // the instruction end.
LGap* gap = chunk_->GetGapAt(gap_index); LGap* gap = GapAt(gap_index);
LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE); LParallelMove* move = gap->GetOrCreateParallelMove(LGap::BEFORE);
move->AddMove(first_output, range->GetSpillOperand()); move->AddMove(first_output, range->GetSpillOperand());
} }
...@@ -818,8 +818,8 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first, ...@@ -818,8 +818,8 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first,
// Handle fixed input operands of second instruction. // Handle fixed input operands of second instruction.
if (second != NULL) { if (second != NULL) {
for (int i = 0; i < second->InputCount(); ++i) { for (UseIterator it(second); it.HasNext(); it.Advance()) {
LUnallocated* cur_input = LUnallocated::cast(second->InputAt(i)); LUnallocated* cur_input = LUnallocated::cast(it.Next());
if (cur_input->HasFixedPolicy()) { if (cur_input->HasFixedPolicy()) {
LUnallocated* input_copy = cur_input->CopyUnconstrained(); LUnallocated* input_copy = cur_input->CopyUnconstrained();
bool is_tagged = HasTaggedValue(cur_input->VirtualRegister()); bool is_tagged = HasTaggedValue(cur_input->VirtualRegister());
...@@ -848,7 +848,7 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first, ...@@ -848,7 +848,7 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first,
if (second != NULL && second->Output() != NULL) { if (second != NULL && second->Output() != NULL) {
LUnallocated* second_output = LUnallocated::cast(second->Output()); LUnallocated* second_output = LUnallocated::cast(second->Output());
if (second_output->HasSameAsInputPolicy()) { if (second_output->HasSameAsInputPolicy()) {
LUnallocated* cur_input = LUnallocated::cast(second->InputAt(0)); LUnallocated* cur_input = LUnallocated::cast(second->FirstInput());
int output_vreg = second_output->VirtualRegister(); int output_vreg = second_output->VirtualRegister();
int input_vreg = cur_input->VirtualRegister(); int input_vreg = cur_input->VirtualRegister();
...@@ -858,7 +858,7 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first, ...@@ -858,7 +858,7 @@ void LAllocator::MeetConstraintsBetween(InstructionSummary* first,
if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
int index = gap_index + 1; int index = gap_index + 1;
LInstruction* instr = chunk_->instructions()->at(index); LInstruction* instr = InstructionAt(index);
if (instr->HasPointerMap()) { if (instr->HasPointerMap()) {
instr->pointer_map()->RecordPointer(input_copy); instr->pointer_map()->RecordPointer(input_copy);
} }
...@@ -886,9 +886,9 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { ...@@ -886,9 +886,9 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
LifetimePosition curr_position = LifetimePosition curr_position =
LifetimePosition::FromInstructionIndex(index); LifetimePosition::FromInstructionIndex(index);
if (chunk_->IsGapAt(index)) { if (IsGapAt(index)) {
// We have a gap at this position. // We have a gap at this position.
LGap* gap = chunk_->GetGapAt(index); LGap* gap = GapAt(index);
LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START); LParallelMove* move = gap->GetOrCreateParallelMove(LGap::START);
const ZoneList<LMoveOperands>* move_operands = move->move_operands(); const ZoneList<LMoveOperands>* move_operands = move->move_operands();
for (int i = 0; i < move_operands->length(); ++i) { for (int i = 0; i < move_operands->length(); ++i) {
...@@ -922,17 +922,17 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { ...@@ -922,17 +922,17 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
} }
} }
} else { } else {
ASSERT(!chunk_->IsGapAt(index)); ASSERT(!IsGapAt(index));
InstructionSummary* summary = GetSummary(index); LInstruction* instr = InstructionAt(index);
if (summary != NULL) { if (instr != NULL) {
LOperand* output = summary->Output(); LOperand* output = instr->Output();
if (output != NULL) { if (output != NULL) {
if (output->IsUnallocated()) live->Remove(output->VirtualRegister()); if (output->IsUnallocated()) live->Remove(output->VirtualRegister());
Define(curr_position, output, NULL); Define(curr_position, output, NULL);
} }
if (summary->IsCall()) { if (instr->IsMarkedAsCall()) {
for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) {
if (output == NULL || !output->IsRegister() || if (output == NULL || !output->IsRegister() ||
output->index() != i) { output->index() != i) {
...@@ -943,7 +943,7 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { ...@@ -943,7 +943,7 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
} }
} }
if (summary->IsCall() || summary->IsSaveDoubles()) { if (instr->IsMarkedAsCall() || instr->IsMarkedAsSaveDoubles()) {
for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) {
if (output == NULL || !output->IsDoubleRegister() || if (output == NULL || !output->IsDoubleRegister() ||
output->index() != i) { output->index() != i) {
...@@ -954,8 +954,8 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { ...@@ -954,8 +954,8 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
} }
} }
for (int i = 0; i < summary->InputCount(); ++i) { for (UseIterator it(instr); it.HasNext(); it.Advance()) {
LOperand* input = summary->InputAt(i); LOperand* input = it.Next();
LifetimePosition use_pos; LifetimePosition use_pos;
if (input->IsUnallocated() && if (input->IsUnallocated() &&
...@@ -969,9 +969,9 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) { ...@@ -969,9 +969,9 @@ void LAllocator::ProcessInstructions(HBasicBlock* block, BitVector* live) {
if (input->IsUnallocated()) live->Add(input->VirtualRegister()); if (input->IsUnallocated()) live->Add(input->VirtualRegister());
} }
for (int i = 0; i < summary->TempCount(); ++i) { for (TempIterator it(instr); it.HasNext(); it.Advance()) {
LOperand* temp = summary->TempAt(i); LOperand* temp = it.Next();
if (summary->IsCall()) { if (instr->IsMarkedAsCall()) {
if (temp->IsRegister()) continue; if (temp->IsRegister()) continue;
if (temp->IsUnallocated()) { if (temp->IsUnallocated()) {
LUnallocated* temp_unalloc = LUnallocated::cast(temp); LUnallocated* temp_unalloc = LUnallocated::cast(temp);
...@@ -1042,9 +1042,9 @@ void LAllocator::Allocate(LChunk* chunk) { ...@@ -1042,9 +1042,9 @@ void LAllocator::Allocate(LChunk* chunk) {
void LAllocator::MeetRegisterConstraints() { void LAllocator::MeetRegisterConstraints() {
HPhase phase("Register constraints", chunk()); HPhase phase("Register constraints", chunk_);
first_artificial_register_ = next_virtual_register_; first_artificial_register_ = next_virtual_register_;
const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
for (int i = 0; i < blocks->length(); ++i) { for (int i = 0; i < blocks->length(); ++i) {
HBasicBlock* block = blocks->at(i); HBasicBlock* block = blocks->at(i);
MeetRegisterConstraints(block); MeetRegisterConstraints(block);
...@@ -1053,10 +1053,10 @@ void LAllocator::MeetRegisterConstraints() { ...@@ -1053,10 +1053,10 @@ void LAllocator::MeetRegisterConstraints() {
void LAllocator::ResolvePhis() { void LAllocator::ResolvePhis() {
HPhase phase("Resolve phis", chunk()); HPhase phase("Resolve phis", chunk_);
// Process the blocks in reverse order. // Process the blocks in reverse order.
const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
HBasicBlock* block = blocks->at(block_id); HBasicBlock* block = blocks->at(block_id);
ResolvePhis(block); ResolvePhis(block);
...@@ -1094,7 +1094,7 @@ void LAllocator::ResolveControlFlow(LiveRange* range, ...@@ -1094,7 +1094,7 @@ void LAllocator::ResolveControlFlow(LiveRange* range,
if (!pred_op->Equals(cur_op)) { if (!pred_op->Equals(cur_op)) {
LGap* gap = NULL; LGap* gap = NULL;
if (block->predecessors()->length() == 1) { if (block->predecessors()->length() == 1) {
gap = chunk_->GetGapAt(block->first_instruction_index()); gap = GapAt(block->first_instruction_index());
} else { } else {
ASSERT(pred->end()->SecondSuccessor() == NULL); ASSERT(pred->end()->SecondSuccessor() == NULL);
gap = GetLastGap(pred); gap = GetLastGap(pred);
...@@ -1107,19 +1107,19 @@ void LAllocator::ResolveControlFlow(LiveRange* range, ...@@ -1107,19 +1107,19 @@ void LAllocator::ResolveControlFlow(LiveRange* range,
LParallelMove* LAllocator::GetConnectingParallelMove(LifetimePosition pos) { LParallelMove* LAllocator::GetConnectingParallelMove(LifetimePosition pos) {
int index = pos.InstructionIndex(); int index = pos.InstructionIndex();
if (chunk_->IsGapAt(index)) { if (IsGapAt(index)) {
LGap* gap = chunk_->GetGapAt(index); LGap* gap = GapAt(index);
return gap->GetOrCreateParallelMove( return gap->GetOrCreateParallelMove(
pos.IsInstructionStart() ? LGap::START : LGap::END); pos.IsInstructionStart() ? LGap::START : LGap::END);
} }
int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1); int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
return chunk_->GetGapAt(gap_pos)->GetOrCreateParallelMove( return GapAt(gap_pos)->GetOrCreateParallelMove(
(gap_pos < index) ? LGap::AFTER : LGap::BEFORE); (gap_pos < index) ? LGap::AFTER : LGap::BEFORE);
} }
HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) { HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) {
LGap* gap = chunk_->GetGapAt(chunk_->NearestGapPos(pos.InstructionIndex())); LGap* gap = GapAt(chunk_->NearestGapPos(pos.InstructionIndex()));
return gap->block(); return gap->block();
} }
...@@ -1166,7 +1166,7 @@ bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const { ...@@ -1166,7 +1166,7 @@ bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const {
void LAllocator::ResolveControlFlow() { void LAllocator::ResolveControlFlow() {
HPhase phase("Resolve control flow", this); HPhase phase("Resolve control flow", this);
const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
for (int block_id = 1; block_id < blocks->length(); ++block_id) { for (int block_id = 1; block_id < blocks->length(); ++block_id) {
HBasicBlock* block = blocks->at(block_id); HBasicBlock* block = blocks->at(block_id);
if (CanEagerlyResolveControlFlow(block)) continue; if (CanEagerlyResolveControlFlow(block)) continue;
...@@ -1189,7 +1189,7 @@ void LAllocator::BuildLiveRanges() { ...@@ -1189,7 +1189,7 @@ void LAllocator::BuildLiveRanges() {
HPhase phase("Build live ranges", this); HPhase phase("Build live ranges", this);
InitializeLivenessAnalysis(); InitializeLivenessAnalysis();
// Process the blocks in reverse order. // Process the blocks in reverse order.
const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) {
HBasicBlock* block = blocks->at(block_id); HBasicBlock* block = blocks->at(block_id);
BitVector* live = ComputeLiveOut(block); BitVector* live = ComputeLiveOut(block);
...@@ -1264,7 +1264,7 @@ void LAllocator::BuildLiveRanges() { ...@@ -1264,7 +1264,7 @@ void LAllocator::BuildLiveRanges() {
found = true; found = true;
int operand_index = iterator.Current(); int operand_index = iterator.Current();
PrintF("Function: %s\n", PrintF("Function: %s\n",
*graph()->info()->function()->debug_name()->ToCString()); *graph_->info()->function()->debug_name()->ToCString());
PrintF("Value %d used before first definition!\n", operand_index); PrintF("Value %d used before first definition!\n", operand_index);
LiveRange* range = LiveRangeFor(operand_index); LiveRange* range = LiveRangeFor(operand_index);
PrintF("First use is at %d\n", range->first_pos()->pos().Value()); PrintF("First use is at %d\n", range->first_pos()->pos().Value());
...@@ -1469,7 +1469,7 @@ void LAllocator::AllocateRegisters() { ...@@ -1469,7 +1469,7 @@ void LAllocator::AllocateRegisters() {
if (current->HasAllocatedSpillOperand()) { if (current->HasAllocatedSpillOperand()) {
TraceAlloc("Live range %d already has a spill operand\n", current->id()); TraceAlloc("Live range %d already has a spill operand\n", current->id());
LifetimePosition next_pos = position; LifetimePosition next_pos = position;
if (chunk_->IsGapAt(next_pos.InstructionIndex())) { if (IsGapAt(next_pos.InstructionIndex())) {
next_pos = next_pos.NextInstruction(); next_pos = next_pos.NextInstruction();
} }
UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos); UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
...@@ -1556,14 +1556,8 @@ void LAllocator::TraceAlloc(const char* msg, ...) { ...@@ -1556,14 +1556,8 @@ void LAllocator::TraceAlloc(const char* msg, ...) {
} }
void LAllocator::RecordUse(HValue* value, LUnallocated* operand) {
operand->set_virtual_register(value->id());
current_summary()->AddInput(operand);
}
bool LAllocator::HasTaggedValue(int virtual_register) const { bool LAllocator::HasTaggedValue(int virtual_register) const {
HValue* value = graph()->LookupValue(virtual_register); HValue* value = graph_->LookupValue(virtual_register);
if (value == NULL) return false; if (value == NULL) return false;
return value->representation().IsTagged(); return value->representation().IsTagged();
} }
...@@ -1571,7 +1565,7 @@ bool LAllocator::HasTaggedValue(int virtual_register) const { ...@@ -1571,7 +1565,7 @@ bool LAllocator::HasTaggedValue(int virtual_register) const {
RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const { RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const {
if (virtual_register < first_artificial_register_) { if (virtual_register < first_artificial_register_) {
HValue* value = graph()->LookupValue(virtual_register); HValue* value = graph_->LookupValue(virtual_register);
if (value != NULL && value->representation().IsDouble()) { if (value != NULL && value->representation().IsDouble()) {
return DOUBLE_REGISTERS; return DOUBLE_REGISTERS;
} }
...@@ -1584,39 +1578,8 @@ RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const { ...@@ -1584,39 +1578,8 @@ RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const {
} }
void LAllocator::MarkAsCall() {
// Call instructions can use only fixed registers as
// temporaries and outputs because all registers
// are blocked by the calling convention.
// Inputs can use either fixed register or have a short lifetime (be
// used at start of the instruction).
InstructionSummary* summary = current_summary();
#ifdef DEBUG
ASSERT(summary->Output() == NULL ||
LUnallocated::cast(summary->Output())->HasFixedPolicy() ||
!LUnallocated::cast(summary->Output())->HasRegisterPolicy());
for (int i = 0; i < summary->InputCount(); i++) {
ASSERT(LUnallocated::cast(summary->InputAt(i))->HasFixedPolicy() ||
LUnallocated::cast(summary->InputAt(i))->IsUsedAtStart() ||
!LUnallocated::cast(summary->InputAt(i))->HasRegisterPolicy());
}
for (int i = 0; i < summary->TempCount(); i++) {
ASSERT(LUnallocated::cast(summary->TempAt(i))->HasFixedPolicy() ||
!LUnallocated::cast(summary->TempAt(i))->HasRegisterPolicy());
}
#endif
summary->MarkAsCall();
}
void LAllocator::MarkAsSaveDoubles() {
current_summary()->MarkAsSaveDoubles();
}
void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) { void LAllocator::RecordDefinition(HInstruction* instr, LUnallocated* operand) {
operand->set_virtual_register(instr->id()); operand->set_virtual_register(instr->id());
current_summary()->SetOutput(operand);
} }
...@@ -1625,40 +1588,16 @@ void LAllocator::RecordTemporary(LUnallocated* operand) { ...@@ -1625,40 +1588,16 @@ void LAllocator::RecordTemporary(LUnallocated* operand) {
if (!operand->HasFixedPolicy()) { if (!operand->HasFixedPolicy()) {
operand->set_virtual_register(next_virtual_register_++); operand->set_virtual_register(next_virtual_register_++);
} }
current_summary()->AddTemp(operand);
}
int LAllocator::max_initial_value_ids() {
return LUnallocated::kMaxVirtualRegisters / 32;
}
void LAllocator::BeginInstruction() {
if (next_summary_ == NULL) {
next_summary_ = new InstructionSummary();
}
summary_stack_.Add(next_summary_);
next_summary_ = NULL;
} }
void LAllocator::SummarizeInstruction(int index) { void LAllocator::RecordUse(HValue* value, LUnallocated* operand) {
InstructionSummary* sum = summary_stack_.RemoveLast(); operand->set_virtual_register(value->id());
if (summaries_.length() <= index) {
summaries_.AddBlock(NULL, index + 1 - summaries_.length());
}
ASSERT(summaries_[index] == NULL);
if (sum->Output() != NULL || sum->InputCount() > 0 || sum->TempCount() > 0) {
summaries_[index] = sum;
} else {
next_summary_ = sum;
}
} }
void LAllocator::OmitInstruction() { int LAllocator::max_initial_value_ids() {
summary_stack_.RemoveLast(); return LUnallocated::kMaxVirtualRegisters / 32;
} }
...@@ -2007,7 +1946,7 @@ void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { ...@@ -2007,7 +1946,7 @@ void LAllocator::SplitAndSpillIntersecting(LiveRange* current) {
bool LAllocator::IsBlockBoundary(LifetimePosition pos) { bool LAllocator::IsBlockBoundary(LifetimePosition pos) {
return pos.IsInstructionStart() && return pos.IsInstructionStart() &&
chunk_->instructions()->at(pos.InstructionIndex())->IsLabel(); InstructionAt(pos.InstructionIndex())->IsLabel();
} }
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "v8.h" #include "v8.h"
#include "data-flow.h" #include "data-flow.h"
#include "lithium.h"
#include "zone.h" #include "zone.h"
namespace v8 { namespace v8 {
...@@ -153,52 +154,55 @@ enum RegisterKind { ...@@ -153,52 +154,55 @@ enum RegisterKind {
// A register-allocator view of a Lithium instruction. It contains the id of // A register-allocator view of a Lithium instruction. It contains the id of
// the output operand and a list of input operand uses. // the output operand and a list of input operand uses.
class InstructionSummary: public ZoneObject {
class LInstruction;
class LEnvironment;
// Iterator for non-null temp operands.
class TempIterator BASE_EMBEDDED {
public: public:
InstructionSummary() inline explicit TempIterator(LInstruction* instr);
: output_operand_(NULL), inline bool HasNext();
input_count_(0), inline LOperand* Next();
operands_(4), inline void Advance();
is_call_(false),
is_save_doubles_(false) {}
// Output operands.
LOperand* Output() const { return output_operand_; }
void SetOutput(LOperand* output) {
ASSERT(output_operand_ == NULL);
output_operand_ = output;
}
// Input operands. private:
int InputCount() const { return input_count_; } inline int AdvanceToNext(int start);
LOperand* InputAt(int i) const { LInstruction* instr_;
ASSERT(i < input_count_); int limit_;
return operands_[i]; int current_;
} };
void AddInput(LOperand* input) {
operands_.InsertAt(input_count_, input);
input_count_++;
}
// Temporary operands.
int TempCount() const { return operands_.length() - input_count_; }
LOperand* TempAt(int i) const { return operands_[i + input_count_]; }
void AddTemp(LOperand* temp) { operands_.Add(temp); }
void MarkAsCall() { is_call_ = true; } // Iterator for non-constant input operands.
bool IsCall() const { return is_call_; } class InputIterator BASE_EMBEDDED {
public:
inline explicit InputIterator(LInstruction* instr);
inline bool HasNext();
inline LOperand* Next();
inline void Advance();
private:
inline int AdvanceToNext(int start);
LInstruction* instr_;
int limit_;
int current_;
};
void MarkAsSaveDoubles() { is_save_doubles_ = true; } class UseIterator BASE_EMBEDDED {
bool IsSaveDoubles() const { return is_save_doubles_; } public:
inline explicit UseIterator(LInstruction* instr);
inline bool HasNext();
inline LOperand* Next();
inline void Advance();
private: private:
LOperand* output_operand_; InputIterator input_iterator_;
int input_count_; DeepIterator env_iterator_;
ZoneList<LOperand*> operands_;
bool is_call_;
bool is_save_doubles_;
}; };
// Representation of the non-empty interval [start,end[. // Representation of the non-empty interval [start,end[.
class UseInterval: public ZoneObject { class UseInterval: public ZoneObject {
public: public:
...@@ -428,9 +432,6 @@ class LAllocator BASE_EMBEDDED { ...@@ -428,9 +432,6 @@ class LAllocator BASE_EMBEDDED {
public: public:
explicit LAllocator(int first_virtual_register, HGraph* graph) explicit LAllocator(int first_virtual_register, HGraph* graph)
: chunk_(NULL), : chunk_(NULL),
summaries_(0),
next_summary_(NULL),
summary_stack_(2),
live_in_sets_(0), live_in_sets_(0),
live_ranges_(16), live_ranges_(16),
fixed_live_ranges_(8), fixed_live_ranges_(8),
...@@ -457,27 +458,12 @@ class LAllocator BASE_EMBEDDED { ...@@ -457,27 +458,12 @@ class LAllocator BASE_EMBEDDED {
// Record a temporary operand. // Record a temporary operand.
void RecordTemporary(LUnallocated* operand); void RecordTemporary(LUnallocated* operand);
// Marks the current instruction as a call.
void MarkAsCall();
// Marks the current instruction as requiring saving double registers.
void MarkAsSaveDoubles();
// Checks whether the value of a given virtual register is tagged. // Checks whether the value of a given virtual register is tagged.
bool HasTaggedValue(int virtual_register) const; bool HasTaggedValue(int virtual_register) const;
// Returns the register kind required by the given virtual register. // Returns the register kind required by the given virtual register.
RegisterKind RequiredRegisterKind(int virtual_register) const; RegisterKind RequiredRegisterKind(int virtual_register) const;
// Begin a new instruction.
void BeginInstruction();
// Summarize the current instruction.
void SummarizeInstruction(int index);
// Summarize the current instruction.
void OmitInstruction();
// Control max function size. // Control max function size.
static int max_initial_value_ids(); static int max_initial_value_ids();
...@@ -525,8 +511,8 @@ class LAllocator BASE_EMBEDDED { ...@@ -525,8 +511,8 @@ class LAllocator BASE_EMBEDDED {
void AddInitialIntervals(HBasicBlock* block, BitVector* live_out); void AddInitialIntervals(HBasicBlock* block, BitVector* live_out);
void ProcessInstructions(HBasicBlock* block, BitVector* live); void ProcessInstructions(HBasicBlock* block, BitVector* live);
void MeetRegisterConstraints(HBasicBlock* block); void MeetRegisterConstraints(HBasicBlock* block);
void MeetConstraintsBetween(InstructionSummary* first, void MeetConstraintsBetween(LInstruction* first,
InstructionSummary* second, LInstruction* second,
int gap_index); int gap_index);
void ResolvePhis(HBasicBlock* block); void ResolvePhis(HBasicBlock* block);
...@@ -604,12 +590,6 @@ class LAllocator BASE_EMBEDDED { ...@@ -604,12 +590,6 @@ class LAllocator BASE_EMBEDDED {
// Return the block which contains give lifetime position. // Return the block which contains give lifetime position.
HBasicBlock* GetBlock(LifetimePosition pos); HBasicBlock* GetBlock(LifetimePosition pos);
// Current active summary.
InstructionSummary* current_summary() const { return summary_stack_.last(); }
// Get summary for given instruction index.
InstructionSummary* GetSummary(int index) const { return summaries_[index]; }
// Helper methods for the fixed registers. // Helper methods for the fixed registers.
int RegisterCount() const; int RegisterCount() const;
static int FixedLiveRangeID(int index) { return -index - 1; } static int FixedLiveRangeID(int index) { return -index - 1; }
...@@ -618,15 +598,17 @@ class LAllocator BASE_EMBEDDED { ...@@ -618,15 +598,17 @@ class LAllocator BASE_EMBEDDED {
LiveRange* FixedDoubleLiveRangeFor(int index); LiveRange* FixedDoubleLiveRangeFor(int index);
LiveRange* LiveRangeFor(int index); LiveRange* LiveRangeFor(int index);
HPhi* LookupPhi(LOperand* operand) const; HPhi* LookupPhi(LOperand* operand) const;
LGap* GetLastGap(HBasicBlock* block) const; LGap* GetLastGap(HBasicBlock* block);
const char* RegisterName(int allocation_index); const char* RegisterName(int allocation_index);
LChunk* chunk_; inline bool IsGapAt(int index);
ZoneList<InstructionSummary*> summaries_;
InstructionSummary* next_summary_;
ZoneList<InstructionSummary*> summary_stack_; inline LInstruction* InstructionAt(int index);
inline LGap* GapAt(int index);
LChunk* chunk_;
// During liveness analysis keep a mapping from block id to live_in sets // During liveness analysis keep a mapping from block id to live_in sets
// for blocks already analyzed. // for blocks already analyzed.
......
...@@ -509,6 +509,82 @@ class LEnvironment: public ZoneObject { ...@@ -509,6 +509,82 @@ class LEnvironment: public ZoneObject {
friend class LCodegen; friend class LCodegen;
}; };
// Iterates over the non-null, non-constant operands in an environment.
class ShallowIterator BASE_EMBEDDED {
public:
explicit ShallowIterator(LEnvironment* env)
: env_(env),
limit_(env != NULL ? env->values()->length() : 0),
current_(0) {
current_ = AdvanceToNext(0);
}
inline bool HasNext() {
return env_ != NULL && current_ < limit_;
}
inline LOperand* Next() {
ASSERT(HasNext());
return env_->values()->at(current_);
}
inline void Advance() {
current_ = AdvanceToNext(current_ + 1);
}
inline LEnvironment* env() { return env_; }
private:
inline int AdvanceToNext(int start) {
while (start < limit_ &&
(env_->values()->at(start) == NULL ||
env_->values()->at(start)->IsConstantOperand())) {
start++;
}
return start;
}
LEnvironment* env_;
int limit_;
int current_;
};
// Iterator for non-null, non-constant operands incl. outer environments.
class DeepIterator BASE_EMBEDDED {
public:
explicit DeepIterator(LEnvironment* env)
: current_iterator_(env) { }
inline bool HasNext() {
if (current_iterator_.HasNext()) return true;
if (current_iterator_.env() == NULL) return false;
AdvanceToOuter();
return current_iterator_.HasNext();
}
inline LOperand* Next() {
ASSERT(current_iterator_.HasNext());
return current_iterator_.Next();
}
inline void Advance() {
if (current_iterator_.HasNext()) {
current_iterator_.Advance();
} else {
AdvanceToOuter();
}
}
private:
inline void AdvanceToOuter() {
current_iterator_ = ShallowIterator(current_iterator_.env()->outer());
}
ShallowIterator current_iterator_;
};
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_LITHIUM_H_ #endif // V8_LITHIUM_H_
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#if defined(V8_TARGET_ARCH_X64) #if defined(V8_TARGET_ARCH_X64)
#include "lithium-allocator-inl.h"
#include "x64/lithium-x64.h" #include "x64/lithium-x64.h"
#include "x64/lithium-codegen-x64.h" #include "x64/lithium-codegen-x64.h"
...@@ -68,11 +69,35 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, ...@@ -68,11 +69,35 @@ void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
} }
#ifdef DEBUG
void LInstruction::VerifyCall() {
// Call instructions can use only fixed registers as
// temporaries and outputs because all registers
// are blocked by the calling convention.
// Inputs can use either fixed register or have a short lifetime (be
// used at start of the instruction).
ASSERT(Output() == NULL ||
LUnallocated::cast(Output())->HasFixedPolicy() ||
!LUnallocated::cast(Output())->HasRegisterPolicy());
for (UseIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
LUnallocated::cast(operand)->IsUsedAtStart() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
}
for (TempIterator it(this); it.HasNext(); it.Advance()) {
LOperand* operand = it.Next();
ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
!LUnallocated::cast(operand)->HasRegisterPolicy());
}
}
#endif
void LInstruction::PrintTo(StringStream* stream) { void LInstruction::PrintTo(StringStream* stream) {
stream->Add("%s ", this->Mnemonic()); stream->Add("%s ", this->Mnemonic());
if (HasResult()) {
PrintOutputOperandTo(stream); PrintOutputOperandTo(stream);
}
PrintDataTo(stream); PrintDataTo(stream);
...@@ -393,7 +418,7 @@ void LStoreKeyed::PrintDataTo(StringStream* stream) { ...@@ -393,7 +418,7 @@ void LStoreKeyed::PrintDataTo(StringStream* stream) {
} }
int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LGap* gap = new LGap(block); LGap* gap = new LGap(block);
int index = -1; int index = -1;
if (instr->IsControl()) { if (instr->IsControl()) {
...@@ -409,7 +434,6 @@ int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { ...@@ -409,7 +434,6 @@ int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
pointer_maps_.Add(instr->pointer_map()); pointer_maps_.Add(instr->pointer_map());
instr->pointer_map()->set_lithium_position(index); instr->pointer_map()->set_lithium_position(index);
} }
return index;
} }
...@@ -677,7 +701,10 @@ void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { ...@@ -677,7 +701,10 @@ void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
HInstruction* hinstr, HInstruction* hinstr,
CanDeoptimize can_deoptimize) { CanDeoptimize can_deoptimize) {
allocator_->MarkAsCall(); #ifdef DEBUG
instr->VerifyCall();
#endif
instr->MarkAsCall();
instr = AssignPointerMap(instr); instr = AssignPointerMap(instr);
if (hinstr->HasSideEffects()) { if (hinstr->HasSideEffects()) {
...@@ -702,7 +729,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, ...@@ -702,7 +729,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) { LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
allocator_->MarkAsSaveDoubles(); instr->MarkAsSaveDoubles();
return instr; return instr;
} }
...@@ -907,7 +934,6 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { ...@@ -907,7 +934,6 @@ void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
void LChunkBuilder::VisitInstruction(HInstruction* current) { void LChunkBuilder::VisitInstruction(HInstruction* current) {
HInstruction* old_current = current_instruction_; HInstruction* old_current = current_instruction_;
current_instruction_ = current; current_instruction_ = current;
allocator_->BeginInstruction();
if (current->has_position()) position_ = current->position(); if (current->has_position()) position_ = current->position();
LInstruction* instr = current->CompileToLithium(this); LInstruction* instr = current->CompileToLithium(this);
...@@ -930,11 +956,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { ...@@ -930,11 +956,7 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
instr->set_hydrogen_value(current); instr->set_hydrogen_value(current);
} }
int index = chunk_->AddInstruction(instr, current_block_); chunk_->AddInstruction(instr, current_block_);
allocator_->SummarizeInstruction(index);
} else {
// This instruction should be omitted.
allocator_->OmitInstruction();
} }
current_instruction_ = old_current; current_instruction_ = old_current;
} }
......
...@@ -287,7 +287,11 @@ class LCodeGen; ...@@ -287,7 +287,11 @@ class LCodeGen;
class LInstruction: public ZoneObject { class LInstruction: public ZoneObject {
public: public:
LInstruction() LInstruction()
: hydrogen_value_(NULL) { } : environment_(NULL),
hydrogen_value_(NULL),
is_call_(false),
is_save_doubles_(false) { }
virtual ~LInstruction() { } virtual ~LInstruction() { }
virtual void CompileToNative(LCodeGen* generator) = 0; virtual void CompileToNative(LCodeGen* generator) = 0;
...@@ -304,16 +308,14 @@ class LInstruction: public ZoneObject { ...@@ -304,16 +308,14 @@ class LInstruction: public ZoneObject {
virtual bool IsControl() const { return false; } virtual bool IsControl() const { return false; }
virtual void SetBranchTargets(int true_block_id, int false_block_id) { } virtual void SetBranchTargets(int true_block_id, int false_block_id) { }
void set_environment(LEnvironment* env) { environment_.set(env); } void set_environment(LEnvironment* env) { environment_ = env; }
LEnvironment* environment() const { return environment_.get(); } LEnvironment* environment() const { return environment_; }
bool HasEnvironment() const { return environment_.is_set(); } bool HasEnvironment() const { return environment_ != NULL; }
void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); } void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
LPointerMap* pointer_map() const { return pointer_map_.get(); } LPointerMap* pointer_map() const { return pointer_map_.get(); }
bool HasPointerMap() const { return pointer_map_.is_set(); } bool HasPointerMap() const { return pointer_map_.is_set(); }
virtual bool HasResult() const = 0;
void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; } void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
HValue* hydrogen_value() const { return hydrogen_value_; } HValue* hydrogen_value() const { return hydrogen_value_; }
...@@ -327,11 +329,35 @@ class LInstruction: public ZoneObject { ...@@ -327,11 +329,35 @@ class LInstruction: public ZoneObject {
return deoptimization_environment_.is_set(); return deoptimization_environment_.is_set();
} }
void MarkAsCall() { is_call_ = true; }
void MarkAsSaveDoubles() { is_save_doubles_ = true; }
// Interface to the register allocator and iterators.
bool IsMarkedAsCall() const { return is_call_; }
bool IsMarkedAsSaveDoubles() const { return is_save_doubles_; }
virtual bool HasResult() const = 0;
virtual LOperand* result() = 0;
virtual int InputCount() = 0;
virtual LOperand* InputAt(int i) = 0;
virtual int TempCount() = 0;
virtual LOperand* TempAt(int i) = 0;
LOperand* FirstInput() { return InputAt(0); }
LOperand* Output() { return HasResult() ? result() : NULL; }
#ifdef DEBUG
void VerifyCall();
#endif
private: private:
SetOncePointer<LEnvironment> environment_; LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_; SetOncePointer<LPointerMap> pointer_map_;
HValue* hydrogen_value_; HValue* hydrogen_value_;
SetOncePointer<LEnvironment> deoptimization_environment_; SetOncePointer<LEnvironment> deoptimization_environment_;
bool is_call_;
bool is_save_doubles_;
}; };
...@@ -358,6 +384,11 @@ class OperandContainer<ElementType, 0> { ...@@ -358,6 +384,11 @@ class OperandContainer<ElementType, 0> {
public: public:
int length() { return 0; } int length() { return 0; }
void PrintOperandsTo(StringStream* stream) { } void PrintOperandsTo(StringStream* stream) { }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
return t;
}
}; };
...@@ -1785,7 +1816,7 @@ class LChunk: public ZoneObject { ...@@ -1785,7 +1816,7 @@ class LChunk: public ZoneObject {
pointer_maps_(8), pointer_maps_(8),
inlined_closures_(1) { } inlined_closures_(1) { }
int AddInstruction(LInstruction* instruction, HBasicBlock* block); void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant); LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const; Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const; Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
......
...@@ -441,6 +441,7 @@ ...@@ -441,6 +441,7 @@
'../../src/lithium.h', '../../src/lithium.h',
'../../src/lithium-allocator.cc', '../../src/lithium-allocator.cc',
'../../src/lithium-allocator.h', '../../src/lithium-allocator.h',
'../../src/lithium-allocator-inl.h',
'../../src/liveedit.cc', '../../src/liveedit.cc',
'../../src/liveedit.h', '../../src/liveedit.h',
'../../src/liveobjectlist-inl.h', '../../src/liveobjectlist-inl.h',
......
...@@ -704,6 +704,10 @@ ...@@ -704,6 +704,10 @@
RelativePath="..\..\src\lithium-allocator.h" RelativePath="..\..\src\lithium-allocator.h"
> >
</File> </File>
<File
RelativePath="..\..\src\lithium-allocator-inl.h"
>
</File>
<File <File
RelativePath="..\..\src\ia32\lithium-ia32.cc" RelativePath="..\..\src\ia32\lithium-ia32.cc"
> >
......
...@@ -696,6 +696,10 @@ ...@@ -696,6 +696,10 @@
RelativePath="..\..\src\lithium-allocator.h" RelativePath="..\..\src\lithium-allocator.h"
> >
</File> </File>
<File
RelativePath="..\..\src\lithium-allocator-inl.h"
>
</File>
<File <File
RelativePath="..\..\src\arm\lithium-arm.cc" RelativePath="..\..\src\arm\lithium-arm.cc"
> >
......
...@@ -705,6 +705,10 @@ ...@@ -705,6 +705,10 @@
RelativePath="..\..\src\lithium-allocator.h" RelativePath="..\..\src\lithium-allocator.h"
> >
</File> </File>
<File
RelativePath="..\..\src\lithium-allocator-inl.h"
>
</File>
<File <File
RelativePath="..\..\src\x64\lithium-x64.cc" RelativePath="..\..\src\x64\lithium-x64.cc"
> >
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment