| 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());
|
| }
|
|
|
|
|
|
|