Index: src/x64/lithium-x64.cc |
=================================================================== |
--- src/x64/lithium-x64.cc (revision 6305) |
+++ src/x64/lithium-x64.cc (working copy) |
@@ -738,7 +738,65 @@ |
} |
void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { |
- Abort("Unimplemented: %s", "DoBasicBlock"); |
+ ASSERT(is_building()); |
+ current_block_ = block; |
+ next_block_ = next_block; |
+ if (block->IsStartBlock()) { |
+ block->UpdateEnvironment(graph_->start_environment()); |
+ argument_count_ = 0; |
+ } else if (block->predecessors()->length() == 1) { |
+ // We have a single predecessor => copy environment and outgoing |
+ // argument count from the predecessor. |
+ ASSERT(block->phis()->length() == 0); |
+ HBasicBlock* pred = block->predecessors()->at(0); |
+ HEnvironment* last_environment = pred->last_environment(); |
+ ASSERT(last_environment != NULL); |
+ // Only copy the environment, if it is later used again. |
+ if (pred->end()->SecondSuccessor() == NULL) { |
+ ASSERT(pred->end()->FirstSuccessor() == block); |
+ } else { |
+ if (pred->end()->FirstSuccessor()->block_id() > block->block_id() || |
+ pred->end()->SecondSuccessor()->block_id() > block->block_id()) { |
+ last_environment = last_environment->Copy(); |
+ } |
+ } |
+ block->UpdateEnvironment(last_environment); |
+ ASSERT(pred->argument_count() >= 0); |
+ argument_count_ = pred->argument_count(); |
+ } else { |
+ // We are at a state join => process phis. |
+ HBasicBlock* pred = block->predecessors()->at(0); |
+ // No need to copy the environment, it cannot be used later. |
+ HEnvironment* last_environment = pred->last_environment(); |
+ for (int i = 0; i < block->phis()->length(); ++i) { |
+ HPhi* phi = block->phis()->at(i); |
+ last_environment->SetValueAt(phi->merged_index(), phi); |
+ } |
+ for (int i = 0; i < block->deleted_phis()->length(); ++i) { |
+ last_environment->SetValueAt(block->deleted_phis()->at(i), |
+ graph_->GetConstantUndefined()); |
+ } |
+ block->UpdateEnvironment(last_environment); |
+ // Pick up the outgoing argument count of one of the predecessors. |
+ argument_count_ = pred->argument_count(); |
+ } |
+ HInstruction* current = block->first(); |
+ int start = chunk_->instructions()->length(); |
+ while (current != NULL && !is_aborted()) { |
+ // Code for constants in registers is generated lazily. |
+ if (!current->EmitAtUses()) { |
+ VisitInstruction(current); |
+ } |
+ current = current->next(); |
+ } |
+ int end = chunk_->instructions()->length() - 1; |
+ if (end >= start) { |
+ block->set_first_instruction_index(start); |
+ block->set_last_instruction_index(end); |
+ } |
+ block->set_argument_count(argument_count_); |
+ next_block_ = NULL; |
+ current_block_ = NULL; |
} |
@@ -808,8 +866,11 @@ |
LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { |
- Abort("Unimplemented: %s", "DoGoto"); |
- return NULL; |
+ LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(), |
+ instr->include_stack_check()); |
+ return (instr->include_stack_check()) |
+ ? AssignPointerMap(result) |
+ : result; |
} |
@@ -1131,14 +1192,24 @@ |
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { |
- Abort("Unimplemented: %s", "DoReturn"); |
- return NULL; |
+ return new LReturn(UseFixed(instr->value(), rax)); |
} |
LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
- Abort("Unimplemented: %s", "DoConstant"); |
- return NULL; |
+ Representation r = instr->representation(); |
+ if (r.IsInteger32()) { |
+ int32_t value = instr->Integer32Value(); |
+ return DefineAsRegister(new LConstantI(value)); |
+ } else if (r.IsDouble()) { |
+ double value = instr->DoubleValue(); |
+ return DefineAsRegister(new LConstantD(value)); |
+ } else if (r.IsTagged()) { |
+ return DefineAsRegister(new LConstantT(instr->handle())); |
+ } else { |
+ UNREACHABLE(); |
+ return NULL; |
+ } |
} |
@@ -1254,8 +1325,8 @@ |
LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
- Abort("Unimplemented: %s", "DoParameter"); |
- return NULL; |
+ int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
+ return DefineAsSpilled(new LParameter, spill_index); |
} |
@@ -1295,14 +1366,39 @@ |
} |
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
- Abort("Unimplemented: %s", "DoSimulate"); |
+ HEnvironment* env = current_block_->last_environment(); |
+ ASSERT(env != NULL); |
+ |
+ env->set_ast_id(instr->ast_id()); |
+ |
+ env->Drop(instr->pop_count()); |
+ for (int i = 0; i < instr->values()->length(); ++i) { |
+ HValue* value = instr->values()->at(i); |
+ if (instr->HasAssignedIndexAt(i)) { |
+ env->Bind(instr->GetAssignedIndexAt(i), value); |
+ } else { |
+ env->Push(value); |
+ } |
+ } |
+ ASSERT(env->length() == instr->environment_length()); |
+ |
+ // If there is an instruction pending deoptimization environment create a |
+ // lazy bailout instruction to capture the environment. |
+ if (pending_deoptimization_ast_id_ == instr->ast_id()) { |
+ LLazyBailout* lazy_bailout = new LLazyBailout; |
+ LInstruction* result = AssignEnvironment(lazy_bailout); |
+ instructions_pending_deoptimization_environment_-> |
+ set_deoptimization_environment(result->environment()); |
+ ClearInstructionPendingDeoptimizationEnvironment(); |
+ return result; |
+ } |
+ |
return NULL; |
} |
LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { |
- Abort("Unimplemented: %s", "DoStackCheck"); |
- return NULL; |
+ return MarkAsCall(new LStackCheck, instr); |
} |