diff options
Diffstat (limited to 'src/3rdparty/v8/src/lithium.cc')
-rw-r--r-- | src/3rdparty/v8/src/lithium.cc | 213 |
1 files changed, 206 insertions, 7 deletions
diff --git a/src/3rdparty/v8/src/lithium.cc b/src/3rdparty/v8/src/lithium.cc index c41cce8..eb2198d 100644 --- a/src/3rdparty/v8/src/lithium.cc +++ b/src/3rdparty/v8/src/lithium.cc @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 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: @@ -27,6 +27,23 @@ #include "v8.h" #include "lithium.h" +#include "scopes.h" + +#if V8_TARGET_ARCH_IA32 +#include "ia32/lithium-ia32.h" +#include "ia32/lithium-codegen-ia32.h" +#elif V8_TARGET_ARCH_X64 +#include "x64/lithium-x64.h" +#include "x64/lithium-codegen-x64.h" +#elif V8_TARGET_ARCH_ARM +#include "arm/lithium-arm.h" +#include "arm/lithium-codegen-arm.h" +#elif V8_TARGET_ARCH_MIPS +#include "mips/lithium-mips.h" +#include "mips/lithium-codegen-mips.h" +#else +#error "Unknown architecture." +#endif namespace v8 { namespace internal { @@ -156,7 +173,7 @@ void LParallelMove::PrintDataTo(StringStream* stream) const { void LEnvironment::PrintTo(StringStream* stream) { - stream->Add("[id=%d|", ast_id()); + stream->Add("[id=%d|", ast_id().ToInt()); stream->Add("[parameters=%d|", parameter_count()); stream->Add("[arguments_stack_height=%d|", arguments_stack_height()); for (int i = 0; i < values_.length(); ++i) { @@ -171,11 +188,11 @@ void LEnvironment::PrintTo(StringStream* stream) { } -void LPointerMap::RecordPointer(LOperand* op) { +void LPointerMap::RecordPointer(LOperand* op, Zone* zone) { // Do not record arguments as pointers. if (op->IsStackSlot() && op->index() < 0) return; ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); - pointer_operands_.Add(op); + pointer_operands_.Add(op, zone); } @@ -192,11 +209,11 @@ void LPointerMap::RemovePointer(LOperand* op) { } -void LPointerMap::RecordUntagged(LOperand* op) { +void LPointerMap::RecordUntagged(LOperand* op, Zone* zone) { // Do not record arguments as pointers. if (op->IsStackSlot() && op->index() < 0) return; ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); - untagged_operands_.Add(op); + untagged_operands_.Add(op, zone); } @@ -225,9 +242,12 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) { return 2; case EXTERNAL_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS: + case FAST_HOLEY_DOUBLE_ELEMENTS: return 3; - case FAST_SMI_ONLY_ELEMENTS: + case FAST_SMI_ELEMENTS: case FAST_ELEMENTS: + case FAST_HOLEY_SMI_ELEMENTS: + case FAST_HOLEY_ELEMENTS: case DICTIONARY_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS: return kPointerSizeLog2; @@ -237,4 +257,183 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) { } +LLabel* LChunk::GetLabel(int block_id) const { + HBasicBlock* block = graph_->blocks()->at(block_id); + int first_instruction = block->first_instruction_index(); + return LLabel::cast(instructions_[first_instruction]); +} + + +int LChunk::LookupDestination(int block_id) const { + LLabel* cur = GetLabel(block_id); + while (cur->replacement() != NULL) { + cur = cur->replacement(); + } + return cur->block_id(); +} + +Label* LChunk::GetAssemblyLabel(int block_id) const { + LLabel* label = GetLabel(block_id); + ASSERT(!label->HasReplacement()); + return label->label(); +} + +void LChunk::MarkEmptyBlocks() { + HPhase phase("L_Mark empty blocks", this); + for (int i = 0; i < graph()->blocks()->length(); ++i) { + HBasicBlock* block = graph()->blocks()->at(i); + int first = block->first_instruction_index(); + int last = block->last_instruction_index(); + LInstruction* first_instr = instructions()->at(first); + LInstruction* last_instr = instructions()->at(last); + + LLabel* label = LLabel::cast(first_instr); + if (last_instr->IsGoto()) { + LGoto* goto_instr = LGoto::cast(last_instr); + if (label->IsRedundant() && + !label->is_loop_header()) { + bool can_eliminate = true; + for (int i = first + 1; i < last && can_eliminate; ++i) { + LInstruction* cur = instructions()->at(i); + if (cur->IsGap()) { + LGap* gap = LGap::cast(cur); + if (!gap->IsRedundant()) { + can_eliminate = false; + } + } else { + can_eliminate = false; + } + } + + if (can_eliminate) { + label->set_replacement(GetLabel(goto_instr->block_id())); + } + } + } + } +} + + +void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { + LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block); + int index = -1; + if (instr->IsControl()) { + instructions_.Add(gap, zone()); + index = instructions_.length(); + instructions_.Add(instr, zone()); + } else { + index = instructions_.length(); + instructions_.Add(instr, zone()); + instructions_.Add(gap, zone()); + } + if (instr->HasPointerMap()) { + pointer_maps_.Add(instr->pointer_map(), zone()); + instr->pointer_map()->set_lithium_position(index); + } +} + + +LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { + return LConstantOperand::Create(constant->id(), zone()); +} + + +int LChunk::GetParameterStackSlot(int index) const { + // The receiver is at index 0, the first parameter at index 1, so we + // shift all parameter indexes down by the number of parameters, and + // make sure they end up negative so they are distinguishable from + // spill slots. + int result = index - info()->scope()->num_parameters() - 1; + ASSERT(result < 0); + return result; +} + + +// A parameter relative to ebp in the arguments stub. +int LChunk::ParameterAt(int index) { + ASSERT(-1 <= index); // -1 is the receiver. + return (1 + info()->scope()->num_parameters() - index) * + kPointerSize; +} + + +LGap* LChunk::GetGapAt(int index) const { + return LGap::cast(instructions_[index]); +} + + +bool LChunk::IsGapAt(int index) const { + return instructions_[index]->IsGap(); +} + + +int LChunk::NearestGapPos(int index) const { + while (!IsGapAt(index)) index--; + return index; +} + + +void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) { + GetGapAt(index)->GetOrCreateParallelMove( + LGap::START, zone())->AddMove(from, to, zone()); +} + + +HConstant* LChunk::LookupConstant(LConstantOperand* operand) const { + return HConstant::cast(graph_->LookupValue(operand->index())); +} + + +Representation LChunk::LookupLiteralRepresentation( + LConstantOperand* operand) const { + return graph_->LookupValue(operand->index())->representation(); +} + + +LChunk* LChunk::NewChunk(HGraph* graph) { + NoHandleAllocation no_handles; + AssertNoAllocation no_gc; + + int values = graph->GetMaximumValueID(); + CompilationInfo* info = graph->info(); + if (values > LUnallocated::kMaxVirtualRegisters) { + info->set_bailout_reason("not enough virtual registers for values"); + return NULL; + } + LAllocator allocator(values, graph); + LChunkBuilder builder(info, graph, &allocator); + LChunk* chunk = builder.Build(); + if (chunk == NULL) return NULL; + + if (!allocator.Allocate(chunk)) { + info->set_bailout_reason("not enough virtual registers (regalloc)"); + return NULL; + } + + return chunk; +} + + +Handle<Code> LChunk::Codegen() { + MacroAssembler assembler(info()->isolate(), NULL, 0); + LCodeGen generator(this, &assembler, info()); + + MarkEmptyBlocks(); + + if (generator.GenerateCode()) { + if (FLAG_trace_codegen) { + PrintF("Crankshaft Compiler - "); + } + CodeGenerator::MakeCodePrologue(info()); + Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); + Handle<Code> code = + CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); + generator.FinishCode(code); + CodeGenerator::PrintCode(code, info()); + return code; + } + return Handle<Code>::null(); +} + + } } // namespace v8::internal |