Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index bf0dd5e315ec5594b08eb8fa58de2593195d9bc3..050123b2bd1838700da59b54411b5d7dc4875054 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -188,6 +188,10 @@ bool LCodeGen::GenerateDeferredCode() { |
bool LCodeGen::GenerateSafepointTable() { |
ASSERT(is_done()); |
+ // Ensure that patching a deoptimization point won't overwrite the table. |
+ for (int i = 0; i < Assembler::kCallInstructionLength; i++) { |
+ masm()->int3(); |
+ } |
safepoints_.Emit(masm(), StackSlotCount()); |
return !is_aborted(); |
} |
@@ -1391,7 +1395,18 @@ void LCodeGen::DoReturn(LReturn* instr) { |
void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { |
- Abort("Unimplemented: %s", "DoLoadGlobal"); |
+ Register result = ToRegister(instr->result()); |
+ if (result.is(rax)) { |
+ __ load_rax(instr->hydrogen()->cell().location(), |
+ RelocInfo::GLOBAL_PROPERTY_CELL); |
+ } else { |
+ __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL); |
+ __ movq(result, Operand(result, 0)); |
+ } |
+ if (instr->hydrogen()->check_hole_value()) { |
+ __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
+ DeoptimizeIf(equal, instr->environment()); |
+ } |
} |
@@ -1456,7 +1471,26 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { |
void LCodeGen::DoPushArgument(LPushArgument* instr) { |
- Abort("Unimplemented: %s", "DoPushArgument"); |
+ LOperand* argument = instr->InputAt(0); |
+ if (argument->IsConstantOperand()) { |
+ LConstantOperand* const_op = LConstantOperand::cast(argument); |
+ Handle<Object> literal = chunk_->LookupLiteral(const_op); |
+ Representation r = chunk_->LookupLiteralRepresentation(const_op); |
+ if (r.IsInteger32()) { |
+ ASSERT(literal->IsNumber()); |
+ __ push(Immediate(static_cast<int32_t>(literal->Number()))); |
+ } else if (r.IsDouble()) { |
+ Abort("unsupported double immediate"); |
+ } else { |
+ ASSERT(r.IsTagged()); |
+ __ Push(literal); |
+ } |
+ } else if (argument->IsRegister()) { |
+ __ push(ToRegister(argument)); |
+ } else { |
+ ASSERT(!argument->IsDoubleRegister()); |
+ __ push(ToOperand(argument)); |
+ } |
} |
@@ -1564,7 +1598,12 @@ void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
void LCodeGen::DoCallNew(LCallNew* instr) { |
- Abort("Unimplemented: %s", "DoCallNew"); |
+ ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); |
+ ASSERT(ToRegister(instr->result()).is(rax)); |
+ |
+ Handle<Code> builtin(Builtins::builtin(Builtins::JSConstructCall)); |
+ __ Set(rax, instr->arity()); |
+ CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); |
} |
@@ -1724,7 +1763,13 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
- Abort("Unimplemented: %s", "DoCheckSmi"); |
+ LOperand* input = instr->InputAt(0); |
+ ASSERT(input->IsRegister()); |
+ Condition cc = masm()->CheckSmi(ToRegister(input)); |
+ if (instr->condition() != equal) { |
+ cc = NegateCondition(cc); |
+ } |
+ DeoptimizeIf(cc, instr->environment()); |
} |
@@ -1739,7 +1784,12 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
void LCodeGen::DoCheckMap(LCheckMap* instr) { |
- Abort("Unimplemented: %s", "DoCheckMap"); |
+ LOperand* input = instr->InputAt(0); |
+ ASSERT(input->IsRegister()); |
+ Register reg = ToRegister(input); |
+ __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), |
+ instr->hydrogen()->map()); |
+ DeoptimizeIf(not_equal, instr->environment()); |
} |